From 1adf28a2b576e59d2c941f850f59776d385da960 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Sat, 14 Jan 2023 16:06:35 +0100 Subject: [PATCH] repository: properly return invalid data error in LoadUnpacked The retry backend does not return the original error, if its execution is interrupted by canceling the context. Thus, we have to manually ensure that the invalid data error gets returned. Additionally, use the retry backend for some of the repository tests, as this is the configuration which will be used by restic. --- internal/repository/repository.go | 7 +++++++ internal/repository/testing.go | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/internal/repository/repository.go b/internal/repository/repository.go index a5988b54c..df8a6fb68 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -188,6 +188,7 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res h := restic.Handle{Type: t, Name: id.String()} retriedInvalidData := false + var dataErr error err := r.be.Load(ctx, h, 0, 0, func(rd io.Reader) error { // make sure this call is idempotent, in case an error occurs wr := bytes.NewBuffer(buf[:0]) @@ -202,6 +203,9 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res if !retriedInvalidData { retriedInvalidData = true } else { + // with a canceled context there is not guarantee which error will + // be returned by `be.Load`. + dataErr = fmt.Errorf("load(%v): %w", h, restic.ErrInvalidData) cancel() } return restic.ErrInvalidData @@ -210,6 +214,9 @@ func (r *Repository) LoadUnpacked(ctx context.Context, t restic.FileType, id res return nil }) + if dataErr != nil { + return nil, dataErr + } if err != nil { return nil, err } diff --git a/internal/repository/testing.go b/internal/repository/testing.go index 5b2e17366..879650336 100644 --- a/internal/repository/testing.go +++ b/internal/repository/testing.go @@ -8,6 +8,7 @@ import ( "github.com/restic/restic/internal/backend/local" "github.com/restic/restic/internal/backend/mem" + "github.com/restic/restic/internal/backend/retry" "github.com/restic/restic/internal/crypto" "github.com/restic/restic/internal/restic" "github.com/restic/restic/internal/test" @@ -97,11 +98,14 @@ func TestRepositoryWithVersion(t testing.TB, version uint) restic.Repository { // TestOpenLocal opens a local repository. func TestOpenLocal(t testing.TB, dir string) (r restic.Repository) { + var be restic.Backend be, err := local.Open(context.TODO(), local.Config{Path: dir, Connections: 2}) if err != nil { t.Fatal(err) } + be = retry.New(be, 3, nil, nil) + repo, err := New(be, Options{}) if err != nil { t.Fatal(err)