1
0
mirror of https://github.com/rclone/rclone.git synced 2026-03-01 10:51:11 +00:00

Compare commits

...

1 Commits

Author SHA1 Message Date
Nick Craig-Wood
8216d66d18 filter: process all the files and return errors at the end with --files-from
Before this change we stopped processing --files-from files at the
first error which meant that a file with an error (say permission
denied) stopped the other files being copied.

This change processes all the files it can and reports the errors at
the end.

Fixes #9115
2026-01-23 17:37:59 +00:00
2 changed files with 8 additions and 4 deletions

View File

@@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs"
"github.com/rclone/rclone/lib/errcount"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
"golang.org/x/text/unicode/norm" "golang.org/x/text/unicode/norm"
) )
@@ -626,6 +627,7 @@ func (f *Filter) MakeListR(ctx context.Context, NewObject func(ctx context.Conte
remotes = make(chan string, checkers) remotes = make(chan string, checkers)
g, gCtx = errgroup.WithContext(ctx) g, gCtx = errgroup.WithContext(ctx)
) )
ec := errcount.New()
for range checkers { for range checkers {
g.Go(func() (err error) { g.Go(func() (err error) {
var entries = make(fs.DirEntries, 1) var entries = make(fs.DirEntries, 1)
@@ -634,7 +636,8 @@ func (f *Filter) MakeListR(ctx context.Context, NewObject func(ctx context.Conte
if err == fs.ErrorObjectNotFound { if err == fs.ErrorObjectNotFound {
// Skip files that are not found // Skip files that are not found
} else if err != nil { } else if err != nil {
return err fs.Errorf(remote, "--files-from failed to find file: %v", err)
ec.Add(err)
} else { } else {
err = callback(entries) err = callback(entries)
if err != nil { if err != nil {
@@ -654,7 +657,8 @@ func (f *Filter) MakeListR(ctx context.Context, NewObject func(ctx context.Conte
} }
} }
close(remotes) close(remotes)
return g.Wait() ec.Add(g.Wait())
return ec.Err("failed to read --files-from files")
} }
} }

View File

@@ -394,7 +394,7 @@ func TestNewFilterMakeListR(t *testing.T) {
// Now check an error is returned from NewObject // Now check an error is returned from NewObject
require.NoError(t, f.AddFile("error")) require.NoError(t, f.AddFile("error"))
err = listR(context.Background(), "", listRcallback) err = listR(context.Background(), "", listRcallback)
require.EqualError(t, err, assert.AnError.Error()) require.EqualError(t, err, "failed to read --files-from files: assert.AnError general error for testing")
// The checker will exit by the error above // The checker will exit by the error above
ci := fs.GetConfig(context.Background()) ci := fs.GetConfig(context.Background())
@@ -403,7 +403,7 @@ func TestNewFilterMakeListR(t *testing.T) {
// Now check an error is returned from NewObject // Now check an error is returned from NewObject
require.NoError(t, f.AddFile("error")) require.NoError(t, f.AddFile("error"))
err = listR(context.Background(), "", listRcallback) err = listR(context.Background(), "", listRcallback)
require.EqualError(t, err, assert.AnError.Error()) require.EqualError(t, err, "failed to read --files-from files: assert.AnError general error for testing")
} }
func TestNewFilterMinSize(t *testing.T) { func TestNewFilterMinSize(t *testing.T) {