diff --git a/src/restic/backend/id.go b/src/restic/backend/id.go index a37e0edea..2714ee63e 100644 --- a/src/restic/backend/id.go +++ b/src/restic/backend/id.go @@ -25,7 +25,7 @@ func ParseID(s string) (ID, error) { b, err := hex.DecodeString(s) if err != nil { - return ID{}, err + return ID{}, errors.Wrap(err, "hex.DecodeString") } if len(b) != IDSize { @@ -73,7 +73,7 @@ func (id ID) Equal(other ID) bool { func (id ID) EqualString(other string) (bool, error) { s, err := hex.DecodeString(other) if err != nil { - return false, err + return false, errors.Wrap(err, "hex.DecodeString") } id2 := ID{} @@ -97,12 +97,12 @@ func (id *ID) UnmarshalJSON(b []byte) error { var s string err := json.Unmarshal(b, &s) if err != nil { - return err + return errors.Wrap(err, "Unmarshal") } _, err = hex.Decode(id[:], []byte(s)) if err != nil { - return err + return errors.Wrap(err, "hex.Decode") } return nil diff --git a/src/restic/backend/local/local.go b/src/restic/backend/local/local.go index 078f21ad5..c51ee949b 100644 --- a/src/restic/backend/local/local.go +++ b/src/restic/backend/local/local.go @@ -35,7 +35,7 @@ func Open(dir string) (*Local, error) { // test if all necessary dirs are there for _, d := range paths(dir) { if _, err := fs.Stat(d); err != nil { - return nil, errors.Errorf("%s does not exist", d) + return nil, errors.Wrap(err, "Open") } } @@ -55,7 +55,7 @@ func Create(dir string) (*Local, error) { for _, d := range paths(dir) { err := fs.MkdirAll(d, backend.Modes.Dir) if err != nil { - return nil, err + return nil, errors.Wrap(err, "MkdirAll") } } @@ -110,13 +110,13 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) { f, err := fs.Open(filename(b.p, h.Type, h.Name)) if err != nil { - return 0, err + return 0, errors.Wrap(err, "Open") } defer func() { e := f.Close() if err == nil && e != nil { - err = e + err = errors.Wrap(e, "Close") } }() @@ -128,7 +128,7 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) { } if err != nil { - return 0, err + return 0, errors.Wrap(err, "Seek") } return io.ReadFull(f, p) @@ -138,12 +138,12 @@ func (b *Local) Load(h backend.Handle, p []byte, off int64) (n int, err error) { func writeToTempfile(tempdir string, p []byte) (filename string, err error) { tmpfile, err := ioutil.TempFile(tempdir, "temp-") if err != nil { - return "", err + return "", errors.Wrap(err, "TempFile") } n, err := tmpfile.Write(p) if err != nil { - return "", err + return "", errors.Wrap(err, "Write") } if n != len(p) { @@ -151,17 +151,17 @@ func writeToTempfile(tempdir string, p []byte) (filename string, err error) { } if err = tmpfile.Sync(); err != nil { - return "", err + return "", errors.Wrap(err, "Syncn") } err = fs.ClearCache(tmpfile) if err != nil { - return "", err + return "", errors.Wrap(err, "ClearCache") } err = tmpfile.Close() if err != nil { - return "", err + return "", errors.Wrap(err, "Close") } return tmpfile.Name(), nil @@ -191,7 +191,7 @@ func (b *Local) Save(h backend.Handle, p []byte) (err error) { if h.Type == backend.Data { err = fs.MkdirAll(filepath.Dir(filename), backend.Modes.Dir) if err != nil { - return err + return errors.Wrap(err, "MkdirAll") } } @@ -200,13 +200,13 @@ func (b *Local) Save(h backend.Handle, p []byte) (err error) { h, filepath.Base(tmpfile), filepath.Base(filename), err) if err != nil { - return err + return errors.Wrap(err, "Rename") } // set mode to read-only fi, err := fs.Stat(filename) if err != nil { - return err + return errors.Wrap(err, "Stat") } return setNewFileMode(filename, fi) @@ -221,7 +221,7 @@ func (b *Local) Stat(h backend.Handle) (backend.BlobInfo, error) { fi, err := fs.Stat(filename(b.p, h.Type, h.Name)) if err != nil { - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "Stat") } return backend.BlobInfo{Size: fi.Size()}, nil @@ -235,7 +235,7 @@ func (b *Local) Test(t backend.Type, name string) (bool, error) { if os.IsNotExist(errors.Cause(err)) { return false, nil } - return false, err + return false, errors.Wrap(err, "Stat") } return true, nil @@ -249,7 +249,7 @@ func (b *Local) Remove(t backend.Type, name string) error { // reset read-only flag err := fs.Chmod(fn, 0666) if err != nil { - return err + return errors.Wrap(err, "Chmod") } return fs.Remove(fn) @@ -262,13 +262,13 @@ func isFile(fi os.FileInfo) bool { func readdir(d string) (fileInfos []os.FileInfo, err error) { f, e := fs.Open(d) if e != nil { - return nil, e + return nil, errors.Wrap(e, "Open") } defer func() { e := f.Close() if err == nil { - err = e + err = errors.Wrap(e, "Close") } }() diff --git a/src/restic/backend/rest/config.go b/src/restic/backend/rest/config.go index 61a73144a..e59031071 100644 --- a/src/restic/backend/rest/config.go +++ b/src/restic/backend/rest/config.go @@ -22,7 +22,7 @@ func ParseConfig(s string) (interface{}, error) { u, err := url.Parse(s) if err != nil { - return nil, err + return nil, errors.Wrap(err, "url.Parse") } cfg := Config{URL: u} diff --git a/src/restic/backend/rest/rest.go b/src/restic/backend/rest/rest.go index 635c2f4c5..a98fd5a80 100644 --- a/src/restic/backend/rest/rest.go +++ b/src/restic/backend/rest/rest.go @@ -80,7 +80,7 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er if off < 0 { info, err := b.Stat(h) if err != nil { - return 0, err + return 0, errors.Wrap(err, "Stat") } if -off > info.Size { @@ -92,7 +92,7 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er req, err := http.NewRequest("GET", restPath(b.url, h), nil) if err != nil { - return 0, err + return 0, errors.Wrap(err, "http.NewRequest") } req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", off, off+int64(len(p)))) <-b.connChan @@ -104,13 +104,13 @@ func (b *restBackend) Load(h backend.Handle, p []byte, off int64) (n int, err er e := resp.Body.Close() if err == nil { - err = e + err = errors.Wrap(e, "Close") } }() } if err != nil { - return 0, err + return 0, errors.Wrap(err, "client.Do") } if resp.StatusCode != 200 && resp.StatusCode != 206 { return 0, errors.Errorf("unexpected HTTP response code %v", resp.StatusCode) @@ -134,13 +134,13 @@ func (b *restBackend) Save(h backend.Handle, p []byte) (err error) { e := resp.Body.Close() if err == nil { - err = e + err = errors.Wrap(e, "Close") } }() } if err != nil { - return err + return errors.Wrap(err, "client.Post") } if resp.StatusCode != 200 { @@ -160,11 +160,11 @@ func (b *restBackend) Stat(h backend.Handle) (backend.BlobInfo, error) { resp, err := b.client.Head(restPath(b.url, h)) b.connChan <- struct{}{} if err != nil { - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "client.Head") } if err = resp.Body.Close(); err != nil { - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "Close") } if resp.StatusCode != 200 { @@ -201,14 +201,14 @@ func (b *restBackend) Remove(t backend.Type, name string) error { req, err := http.NewRequest("DELETE", restPath(b.url, h), nil) if err != nil { - return err + return errors.Wrap(err, "http.NewRequest") } <-b.connChan resp, err := b.client.Do(req) b.connChan <- struct{}{} if err != nil { - return err + return errors.Wrap(err, "client.Do") } if resp.StatusCode != 200 { diff --git a/src/restic/backend/s3/config.go b/src/restic/backend/s3/config.go index 70991363d..4eda2b0e8 100644 --- a/src/restic/backend/s3/config.go +++ b/src/restic/backend/s3/config.go @@ -32,7 +32,7 @@ func ParseConfig(s string) (interface{}, error) { // bucket name and prefix url, err := url.Parse(s[3:]) if err != nil { - return nil, err + return nil, errors.Wrap(err, "url.Parse") } if url.Path == "" { diff --git a/src/restic/backend/s3/s3.go b/src/restic/backend/s3/s3.go index 6da9cac47..835a7c485 100644 --- a/src/restic/backend/s3/s3.go +++ b/src/restic/backend/s3/s3.go @@ -30,7 +30,7 @@ func Open(cfg Config) (backend.Backend, error) { client, err := minio.New(cfg.Endpoint, cfg.KeyID, cfg.Secret, !cfg.UseHTTP) if err != nil { - return nil, err + return nil, errors.Wrap(err, "minio.New") } be := &s3{client: client, bucketname: cfg.Bucket, prefix: cfg.Prefix} @@ -39,14 +39,14 @@ func Open(cfg Config) (backend.Backend, error) { ok, err := client.BucketExists(cfg.Bucket) if err != nil { debug.Log("s3.Open", "BucketExists(%v) returned err %v, trying to create the bucket", cfg.Bucket, err) - return nil, err + return nil, errors.Wrap(err, "client.BucketExists") } if !ok { // create new bucket with default ACL in default region err = client.MakeBucket(cfg.Bucket, "") if err != nil { - return nil, err + return nil, errors.Wrap(err, "client.MakeBucket") } } @@ -95,20 +95,20 @@ func (be s3) Load(h backend.Handle, p []byte, off int64) (n int, err error) { obj, err = be.client.GetObject(be.bucketname, path) if err != nil { debug.Log("s3.Load", " err %v", err) - return 0, err + return 0, errors.Wrap(err, "client.GetObject") } // make sure that the object is closed properly. defer func() { e := obj.Close() if err == nil { - err = e + err = errors.Wrap(e, "Close") } }() info, err := obj.Stat() if err != nil { - return 0, err + return 0, errors.Wrap(err, "obj.Stat") } // handle negative offsets @@ -179,7 +179,7 @@ func (be s3) Save(h backend.Handle, p []byte) (err error) { n, err := be.client.PutObject(be.bucketname, path, bytes.NewReader(p), "binary/octet-stream") debug.Log("s3.Save", "%v -> %v bytes, err %#v", path, n, err) - return err + return errors.Wrap(err, "client.PutObject") } // Stat returns information about a blob. @@ -192,21 +192,21 @@ func (be s3) Stat(h backend.Handle) (bi backend.BlobInfo, err error) { obj, err = be.client.GetObject(be.bucketname, path) if err != nil { debug.Log("s3.Stat", "GetObject() err %v", err) - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "client.GetObject") } // make sure that the object is closed properly. defer func() { e := obj.Close() if err == nil { - err = e + err = errors.Wrap(e, "Close") } }() fi, err := obj.Stat() if err != nil { debug.Log("s3.Stat", "Stat() err %v", err) - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "Stat") } return backend.BlobInfo{Size: fi.Size}, nil @@ -230,7 +230,7 @@ func (be *s3) Remove(t backend.Type, name string) error { path := be.s3path(t, name) err := be.client.RemoveObject(be.bucketname, path) debug.Log("s3.Remove", "%v %v -> err %v", t, name, err) - return err + return errors.Wrap(err, "client.RemoveObject") } // List returns a channel that yields all names of blobs of type t. A diff --git a/src/restic/backend/sftp/config.go b/src/restic/backend/sftp/config.go index 39609e346..d8e200491 100644 --- a/src/restic/backend/sftp/config.go +++ b/src/restic/backend/sftp/config.go @@ -26,7 +26,7 @@ func ParseConfig(s string) (interface{}, error) { // parse the "sftp://user@host/path" url format url, err := url.Parse(s) if err != nil { - return nil, err + return nil, errors.Wrap(err, "url.Parse") } if url.User != nil { user = url.User.Username() diff --git a/src/restic/backend/sftp/sftp.go b/src/restic/backend/sftp/sftp.go index 43806d24c..c82e29683 100644 --- a/src/restic/backend/sftp/sftp.go +++ b/src/restic/backend/sftp/sftp.go @@ -41,7 +41,7 @@ func startClient(program string, args ...string) (*SFTP, error) { // prefix the errors with the program name stderr, err := cmd.StderrPipe() if err != nil { - return nil, err + return nil, errors.Wrap(err, "cmd.StderrPipe") } go func() { @@ -57,16 +57,16 @@ func startClient(program string, args ...string) (*SFTP, error) { // get stdin and stdout wr, err := cmd.StdinPipe() if err != nil { - return nil, err + return nil, errors.Wrap(err, "cmd.StdinPipe") } rd, err := cmd.StdoutPipe() if err != nil { - return nil, err + return nil, errors.Wrap(err, "cmd.StdoutPipe") } // start the process if err := cmd.Start(); err != nil { - return nil, err + return nil, errors.Wrap(err, "cmd.Start") } // wait in a different goroutine @@ -74,7 +74,7 @@ func startClient(program string, args ...string) (*SFTP, error) { go func() { err := cmd.Wait() debug.Log("sftp.Wait", "ssh command exited, err %v", err) - ch <- err + ch <- errors.Wrap(err, "cmd.Wait") }() // open the SFTP session @@ -182,7 +182,7 @@ func Create(dir string, program string, args ...string) (*SFTP, error) { err = sftp.Close() if err != nil { - return nil, err + return nil, errors.Wrap(err, "Close") } // open backend @@ -274,16 +274,17 @@ func (r *SFTP) renameFile(oldname string, t backend.Type, name string) error { err := r.c.Rename(oldname, filename) if err != nil { - return err + return errors.Wrap(err, "Rename") } // set mode to read-only fi, err := r.c.Lstat(filename) if err != nil { - return err + return errors.Wrap(err, "Lstat") } - return r.c.Chmod(filename, fi.Mode()&os.FileMode(^uint32(0222))) + err = r.c.Chmod(filename, fi.Mode()&os.FileMode(^uint32(0222))) + return errors.Wrap(err, "Chmod") } // Join joins the given paths and cleans them afterwards. This always uses @@ -336,13 +337,13 @@ func (r *SFTP) Load(h backend.Handle, p []byte, off int64) (n int, err error) { f, err := r.c.Open(r.filename(h.Type, h.Name)) if err != nil { - return 0, err + return 0, errors.Wrap(err, "Open") } defer func() { e := f.Close() if err == nil && e != nil { - err = e + err = errors.Wrap(e, "Close") } }() @@ -354,7 +355,7 @@ func (r *SFTP) Load(h backend.Handle, p []byte, off int64) (n int, err error) { } if err != nil { - return 0, err + return 0, errors.Wrap(err, "Seek") } return io.ReadFull(f, p) @@ -380,7 +381,7 @@ func (r *SFTP) Save(h backend.Handle, p []byte) (err error) { n, err := tmpfile.Write(p) if err != nil { - return err + return errors.Wrap(err, "Write") } if n != len(p) { @@ -389,17 +390,13 @@ func (r *SFTP) Save(h backend.Handle, p []byte) (err error) { err = tmpfile.Close() if err != nil { - return err + return errors.Wrap(err, "Close") } err = r.renameFile(filename, h.Type, h.Name) debug.Log("sftp.Save", "save %v: rename %v: %v", h, path.Base(filename), err) - if err != nil { - return errors.Errorf("sftp: renameFile: %v", err) - } - - return nil + return err } // Stat returns information about a blob. @@ -415,7 +412,7 @@ func (r *SFTP) Stat(h backend.Handle) (backend.BlobInfo, error) { fi, err := r.c.Lstat(r.filename(h.Type, h.Name)) if err != nil { - return backend.BlobInfo{}, err + return backend.BlobInfo{}, errors.Wrap(err, "Lstat") } return backend.BlobInfo{Size: fi.Size()}, nil @@ -434,7 +431,7 @@ func (r *SFTP) Test(t backend.Type, name string) (bool, error) { } if err != nil { - return false, err + return false, errors.Wrap(err, "Lstat") } return true, nil diff --git a/src/restic/backend/utils.go b/src/restic/backend/utils.go index 01446a78c..9bd87b4fb 100644 --- a/src/restic/backend/utils.go +++ b/src/restic/backend/utils.go @@ -13,7 +13,7 @@ import ( func LoadAll(be Backend, h Handle, buf []byte) ([]byte, error) { fi, err := be.Stat(h) if err != nil { - return nil, err + return nil, errors.Wrap(err, "Stat") } if fi.Size > int64(len(buf)) {