Return error on not found from ListFn
This changes `ListFn`'s implementation so that if it encounters a not found error, instead of sending a fatal error to log, it coordinates the return of the error between checker goroutines and sends it back to the caller. The main impetus here is that it allows an external program compiling against rclone as a package to handle a not found, where it currently it cannot. This does change error output on a not found a little bit, we go from this: 2017/01/09 21:14:03 directory not found To this: 2017/01/09 21:13:44 Failed to ls: directory not found
This commit is contained in:
parent
a7d8ccd265
commit
3b1e0b66bb
2 changed files with 17 additions and 4 deletions
14
fs/lister.go
14
fs/lister.go
|
@ -20,6 +20,7 @@ type Lister struct {
|
||||||
finished sync.Once
|
finished sync.Once
|
||||||
level int
|
level int
|
||||||
filter *Filter
|
filter *Filter
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLister creates a Lister object.
|
// NewLister creates a Lister object.
|
||||||
|
@ -154,6 +155,14 @@ func (o *Lister) AddDir(dir *Dir) (abort bool) {
|
||||||
return false
|
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
|
// IncludeDirectory returns whether this directory should be
|
||||||
// included in the listing (and recursed into or not).
|
// included in the listing (and recursed into or not).
|
||||||
func (o *Lister) IncludeDirectory(remote string) bool {
|
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,
|
// Multiple goroutines can set the error state concurrently,
|
||||||
// but only the first will be returned to the caller.
|
// but only the first will be returned to the caller.
|
||||||
func (o *Lister) SetError(err error) {
|
func (o *Lister) SetError(err error) {
|
||||||
o.mu.RLock()
|
o.mu.Lock()
|
||||||
if err != nil && !o.abort {
|
if err != nil && !o.abort {
|
||||||
|
o.err = err
|
||||||
o.results <- listerResult{Err: err}
|
o.results <- listerResult{Err: err}
|
||||||
}
|
}
|
||||||
o.mu.RUnlock()
|
o.mu.Unlock()
|
||||||
o.Finished()
|
o.Finished()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -654,7 +654,10 @@ func ListFn(f Fs, fn func(Object)) error {
|
||||||
for {
|
for {
|
||||||
o, err := list.GetObject()
|
o, err := list.GetObject()
|
||||||
if err != nil {
|
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
|
// check if we are finished
|
||||||
if o == nil {
|
if o == nil {
|
||||||
|
@ -667,7 +670,7 @@ func ListFn(f Fs, fn func(Object)) error {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return nil
|
return list.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// mutex for synchronized output
|
// mutex for synchronized output
|
||||||
|
|
Loading…
Reference in a new issue