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.
This commit is contained in:
Michael Eischer 2023-01-14 16:06:35 +01:00
parent 6d9675c323
commit 1adf28a2b5
2 changed files with 11 additions and 0 deletions

View File

@ -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
}

View File

@ -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)