Modernize error handling in local backend

* Stop prepending the operation name: it's already part of os.PathError,
  leading to repetitive errors like "Chmod: chmod /foo/bar: operation not
  permitted".

* Use errors.Is to check for specific errors.
This commit is contained in:
greatroar 2021-06-07 19:26:25 +02:00
parent d7322a5f36
commit e5f0f67ba0
2 changed files with 13 additions and 11 deletions

View file

@ -64,7 +64,7 @@ func Create(ctx context.Context, cfg Config) (*Local, error) {
for _, d := range be.Paths() { for _, d := range be.Paths() {
err := fs.MkdirAll(d, backend.Modes.Dir) err := fs.MkdirAll(d, backend.Modes.Dir)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "MkdirAll") return nil, errors.WithStack(err)
} }
} }
@ -78,7 +78,7 @@ func (b *Local) Location() string {
// IsNotExist returns true if the error is caused by a non existing file. // IsNotExist returns true if the error is caused by a non existing file.
func (b *Local) IsNotExist(err error) bool { func (b *Local) IsNotExist(err error) bool {
return os.IsNotExist(errors.Cause(err)) return errors.Is(err, os.ErrNotExist)
} }
// Save stores data in the backend at the handle. // Save stores data in the backend at the handle.
@ -114,14 +114,14 @@ func (b *Local) Save(ctx context.Context, h restic.Handle, rd restic.RewindReade
} }
if err != nil { if err != nil {
return errors.Wrap(err, "OpenFile") return errors.WithStack(err)
} }
// save data, then sync // save data, then sync
wbytes, err := io.Copy(f, rd) wbytes, err := io.Copy(f, rd)
if err != nil { if err != nil {
_ = f.Close() _ = f.Close()
return errors.Wrap(err, "Write") return errors.WithStack(err)
} }
// sanity check // sanity check
if wbytes != rd.Length() { if wbytes != rd.Length() {
@ -135,13 +135,13 @@ func (b *Local) Save(ctx context.Context, h restic.Handle, rd restic.RewindReade
// ignore error if filesystem does not support the sync operation // ignore error if filesystem does not support the sync operation
if !isNotSupported { if !isNotSupported {
_ = f.Close() _ = f.Close()
return errors.Wrap(err, "Sync") return errors.WithStack(err)
} }
} }
err = f.Close() err = f.Close()
if err != nil { if err != nil {
return errors.Wrap(err, "Close") return errors.WithStack(err)
} }
// try to mark file as read-only to avoid accidential modifications // try to mark file as read-only to avoid accidential modifications
@ -149,7 +149,7 @@ func (b *Local) Save(ctx context.Context, h restic.Handle, rd restic.RewindReade
// e.g. exfat and network file systems with certain mount options // e.g. exfat and network file systems with certain mount options
err = setFileReadonly(filename, backend.Modes.File) err = setFileReadonly(filename, backend.Modes.File)
if err != nil && !os.IsPermission(err) { if err != nil && !os.IsPermission(err) {
return errors.Wrap(err, "Chmod") return errors.WithStack(err)
} }
return nil return nil
@ -202,7 +202,7 @@ func (b *Local) Stat(ctx context.Context, h restic.Handle) (restic.FileInfo, err
fi, err := fs.Stat(b.Filename(h)) fi, err := fs.Stat(b.Filename(h))
if err != nil { if err != nil {
return restic.FileInfo{}, errors.Wrap(err, "Stat") return restic.FileInfo{}, errors.WithStack(err)
} }
return restic.FileInfo{Size: fi.Size(), Name: h.Name}, nil return restic.FileInfo{Size: fi.Size(), Name: h.Name}, nil
@ -213,10 +213,10 @@ func (b *Local) Test(ctx context.Context, h restic.Handle) (bool, error) {
debug.Log("Test %v", h) debug.Log("Test %v", h)
_, err := fs.Stat(b.Filename(h)) _, err := fs.Stat(b.Filename(h))
if err != nil { if err != nil {
if os.IsNotExist(errors.Cause(err)) { if b.IsNotExist(err) {
return false, nil return false, nil
} }
return false, errors.Wrap(err, "Stat") return false, errors.WithStack(err)
} }
return true, nil return true, nil
@ -230,7 +230,7 @@ func (b *Local) Remove(ctx context.Context, h restic.Handle) error {
// reset read-only flag // reset read-only flag
err := fs.Chmod(fn, 0666) err := fs.Chmod(fn, 0666)
if err != nil && !os.IsPermission(err) { if err != nil && !os.IsPermission(err) {
return errors.Wrap(err, "Chmod") return errors.WithStack(err)
} }
return fs.Remove(fn) return fs.Remove(fn)

View file

@ -27,6 +27,8 @@ var Wrapf = errors.Wrapf
// returns nil. // returns nil.
var WithMessage = errors.WithMessage var WithMessage = errors.WithMessage
var WithStack = errors.WithStack
// Cause returns the cause of an error. It will also unwrap certain errors, // Cause returns the cause of an error. It will also unwrap certain errors,
// e.g. *url.Error returned by the net/http client. // e.g. *url.Error returned by the net/http client.
func Cause(err error) error { func Cause(err error) error {