From 63e32c44c014b40974f466926c28092734f084b7 Mon Sep 17 00:00:00 2001 From: greatroar <@> Date: Tue, 10 Nov 2020 22:43:18 +0100 Subject: [PATCH] Improve error reporting from restic diff Instead of a stacktrace, restic diff 111 222 now reports: Fatal: no matching ID found for prefix "111" --- cmd/restic/cmd_diff.go | 3 +-- internal/restic/backend_find.go | 27 +++++++++++++++++---------- internal/restic/backend_find_test.go | 11 ++++++----- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/cmd/restic/cmd_diff.go b/cmd/restic/cmd_diff.go index f1b099ede..5197f559d 100644 --- a/cmd/restic/cmd_diff.go +++ b/cmd/restic/cmd_diff.go @@ -55,9 +55,8 @@ func init() { func loadSnapshot(ctx context.Context, repo *repository.Repository, desc string) (*restic.Snapshot, error) { id, err := restic.FindSnapshot(ctx, repo, desc) if err != nil { - return nil, err + return nil, errors.Fatal(err.Error()) } - return restic.LoadSnapshot(ctx, repo, id) } diff --git a/internal/restic/backend_find.go b/internal/restic/backend_find.go index ec85a957a..631c7088a 100644 --- a/internal/restic/backend_find.go +++ b/internal/restic/backend_find.go @@ -2,17 +2,24 @@ package restic import ( "context" - - "github.com/restic/restic/internal/errors" + "fmt" ) -// ErrNoIDPrefixFound is returned by Find() when no ID for the given prefix -// could be found. -var ErrNoIDPrefixFound = errors.New("no matching ID found") +// A MultipleIDMatchesError is returned by Find() when multiple IDs with a +// given prefix are found. +type MultipleIDMatchesError struct{ prefix string } -// ErrMultipleIDMatches is returned by Find() when multiple IDs with the given -// prefix are found. -var ErrMultipleIDMatches = errors.New("multiple IDs with prefix found") +func (e *MultipleIDMatchesError) Error() string { + return fmt.Sprintf("multiple IDs with prefix %s found", e.prefix) +} + +// A NoIDByPrefixError is returned by Find() when no ID for a given prefix +// could be found. +type NoIDByPrefixError struct{ prefix string } + +func (e *NoIDByPrefixError) Error() string { + return fmt.Sprintf("no matching ID found for prefix %q", e.prefix) +} // Find loads the list of all files of type t and searches for names which // start with prefix. If none is found, nil and ErrNoIDPrefixFound is returned. @@ -28,7 +35,7 @@ func Find(ctx context.Context, be Lister, t FileType, prefix string) (string, er if match == "" { match = fi.Name } else { - return ErrMultipleIDMatches + return &MultipleIDMatchesError{prefix} } } @@ -43,7 +50,7 @@ func Find(ctx context.Context, be Lister, t FileType, prefix string) (string, er return match, nil } - return "", ErrNoIDPrefixFound + return "", &NoIDByPrefixError{prefix} } const minPrefixLength = 8 diff --git a/internal/restic/backend_find_test.go b/internal/restic/backend_find_test.go index 557e1367b..52eb38ef3 100644 --- a/internal/restic/backend_find_test.go +++ b/internal/restic/backend_find_test.go @@ -2,6 +2,7 @@ package restic import ( "context" + "strings" "testing" ) @@ -48,7 +49,7 @@ func TestFind(t *testing.T) { } f, err = Find(context.TODO(), m, SnapshotFile, "NotAPrefix") - if err != ErrNoIDPrefixFound { + if _, ok := err.(*NoIDByPrefixError); !ok || !strings.Contains(err.Error(), "NotAPrefix") { t.Error("Expected no snapshots to be found.") } if f != "" { @@ -58,8 +59,8 @@ func TestFind(t *testing.T) { // Try to match with a prefix longer than any ID. extraLengthID := samples[0].String() + "f" f, err = Find(context.TODO(), m, SnapshotFile, extraLengthID) - if err != ErrNoIDPrefixFound { - t.Error("Expected no snapshots to be matched.") + if _, ok := err.(*NoIDByPrefixError); !ok || !strings.Contains(err.Error(), extraLengthID) { + t.Errorf("Wrong error %v for no snapshots matched", err) } if f != "" { t.Errorf("Find should not return a match on error.") @@ -67,8 +68,8 @@ func TestFind(t *testing.T) { // Use a prefix that will match the prefix of multiple Ids in `samples`. f, err = Find(context.TODO(), m, SnapshotFile, "20bdc140") - if err != ErrMultipleIDMatches { - t.Error("Expected multiple snapshots to be matched.") + if _, ok := err.(*MultipleIDMatchesError); !ok { + t.Errorf("Wrong error %v for multiple snapshots", err) } if f != "" { t.Errorf("Find should not return a match on error.")