diff --git a/fs/lister.go b/fs/lister.go index c9daf5838..a9fe4011e 100644 --- a/fs/lister.go +++ b/fs/lister.go @@ -20,6 +20,7 @@ type Lister struct { finished sync.Once level int filter *Filter + err error } // NewLister creates a Lister object. @@ -154,6 +155,14 @@ func (o *Lister) AddDir(dir *Dir) (abort bool) { return false } +// Error returns a globally application error that's been set on the Lister +// object. +func (o *Lister) Error() error { + o.mu.RLock() + defer o.mu.RUnlock() + return o.err +} + // IncludeDirectory returns whether this directory should be // included in the listing (and recursed into or not). func (o *Lister) IncludeDirectory(remote string) bool { @@ -168,11 +177,12 @@ func (o *Lister) IncludeDirectory(remote string) bool { // Multiple goroutines can set the error state concurrently, // but only the first will be returned to the caller. func (o *Lister) SetError(err error) { - o.mu.RLock() + o.mu.Lock() if err != nil && !o.abort { + o.err = err o.results <- listerResult{Err: err} } - o.mu.RUnlock() + o.mu.Unlock() o.Finished() } diff --git a/fs/operations.go b/fs/operations.go index 985420a01..bade42513 100644 --- a/fs/operations.go +++ b/fs/operations.go @@ -654,7 +654,10 @@ func ListFn(f Fs, fn func(Object)) error { for { o, err := list.GetObject() if err != nil { - log.Fatal(err) + // The error will be persisted within the Lister object and + // we'll get an opportunity to return it as we leave this + // function. + return } // check if we are finished if o == nil { @@ -667,7 +670,7 @@ func ListFn(f Fs, fn func(Object)) error { }() } wg.Wait() - return nil + return list.Error() } // mutex for synchronized output