From 593752ee622157e3140babbcd50e61626ce1a7d2 Mon Sep 17 00:00:00 2001 From: Jille Timmermans Date: Sun, 6 Feb 2022 11:23:13 +0100 Subject: [PATCH] Handle errors from closing writable Files Close might do some flushing, so failures to Close might cause data loss. --- go.mod | 1 + go.sum | 2 ++ unionFile.go | 8 ++++++-- util.go | 13 +++++++------ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index b77ae414..d3397756 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/spf13/afero require ( cloud.google.com/go/storage v1.14.0 + github.com/Jille/errchain v1.0.0 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/pkg/sftp v1.13.1 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa diff --git a/go.sum b/go.sum index 1f24646a..5f06d395 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Jille/errchain v1.0.0 h1:S1YDbLdKAADkE1Rbj7A6d0QeoWZIvMzTBeoKjEkw9LA= +github.com/Jille/errchain v1.0.0/go.mod h1:XaSP9ruaReMvv1BmcI52KV4NCmjVFTxjMGmKX9ixzG8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= diff --git a/unionFile.go b/unionFile.go index 34f99a40..ef815633 100644 --- a/unionFile.go +++ b/unionFile.go @@ -5,6 +5,8 @@ import ( "os" "path/filepath" "syscall" + + "github.com/Jille/errchain" ) // The UnionFile implements the afero.File interface and will be returned @@ -32,11 +34,13 @@ func (f *UnionFile) Close() error { // first close base, so we have a newer timestamp in the overlay. If we'd close // the overlay first, we'd get a cacheStale the next time we access this file // -> cache would be useless ;-) + var err error if f.Base != nil { - f.Base.Close() + errchain.Append(&err, f.Base.Close()) } if f.Layer != nil { - return f.Layer.Close() + errchain.Append(&err, f.Layer.Close()) + return err } return BADFD } diff --git a/util.go b/util.go index 4f253f48..8f6055f0 100644 --- a/util.go +++ b/util.go @@ -25,6 +25,7 @@ import ( "strings" "unicode" + "github.com/Jille/errchain" "golang.org/x/text/transform" "golang.org/x/text/unicode/norm" ) @@ -37,12 +38,12 @@ func (a Afero) WriteReader(path string, r io.Reader) (err error) { return WriteReader(a.Fs, path, r) } -func WriteReader(fs Fs, path string, r io.Reader) (err error) { +func WriteReader(fs Fs, path string, r io.Reader) (retErr error) { dir, _ := filepath.Split(path) ospath := filepath.FromSlash(dir) if ospath != "" { - err = fs.MkdirAll(ospath, 0777) // rwx, rw, r + err := fs.MkdirAll(ospath, 0777) // rwx, rw, r if err != nil { if err != os.ErrExist { return err @@ -54,7 +55,7 @@ func WriteReader(fs Fs, path string, r io.Reader) (err error) { if err != nil { return } - defer file.Close() + defer errchain.Call(&retErr, file.Close) _, err = io.Copy(file, r) return @@ -65,12 +66,12 @@ func (a Afero) SafeWriteReader(path string, r io.Reader) (err error) { return SafeWriteReader(a.Fs, path, r) } -func SafeWriteReader(fs Fs, path string, r io.Reader) (err error) { +func SafeWriteReader(fs Fs, path string, r io.Reader) (retErr error) { dir, _ := filepath.Split(path) ospath := filepath.FromSlash(dir) if ospath != "" { - err = fs.MkdirAll(ospath, 0777) // rwx, rw, r + err := fs.MkdirAll(ospath, 0777) // rwx, rw, r if err != nil { return } @@ -88,7 +89,7 @@ func SafeWriteReader(fs Fs, path string, r io.Reader) (err error) { if err != nil { return } - defer file.Close() + defer errchain.Call(&retErr, file.Close) _, err = io.Copy(file, r) return