From dfd0f4c5a458b88857be4a035d910ffc5934f6eb Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 13 Mar 2018 16:05:06 +0000 Subject: [PATCH] sync: when using --backup-dir don't delete files if we can't set their modtime This is a problem when syncing a file which just needed its modtime set with dropbox which can't set the mod time of a file without re-uploading it. Before this change we would delete the file, then the server side move would fail moving the file to the backup-dir because it no longer existed. After this change the destination file is moved to the backup-dir instead of being deleted and the new file is uploaded. Fixes #2134 --- backend/dropbox/dropbox.go | 2 +- fs/operations/operations.go | 10 +++++++--- lib/rest/rest.go | 7 ++++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/backend/dropbox/dropbox.go b/backend/dropbox/dropbox.go index 5b017973c..66fbdbe6c 100644 --- a/backend/dropbox/dropbox.go +++ b/backend/dropbox/dropbox.go @@ -801,7 +801,7 @@ func (o *Object) SetModTime(modTime time.Time) error { // Dropbox doesn't have a way of doing this so returning this // error will cause the file to be deleted first then // re-uploaded to set the time. - return fs.ErrorCantSetModTimeWithoutDelete + return fs.ErrorCantSetModTime } // Storable returns whether this object is storable diff --git a/fs/operations/operations.go b/fs/operations/operations.go index 6a2f48734..891a6c36b 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -178,9 +178,13 @@ func equal(src fs.ObjectInfo, dst fs.Object, sizeOnly, checkSum bool) bool { return false } else if err == fs.ErrorCantSetModTimeWithoutDelete { fs.Debugf(dst, "src and dst identical but can't set mod time without deleting and re-uploading") - err = dst.Remove() - if err != nil { - fs.Errorf(dst, "failed to delete before re-upload: %v", err) + // Remove the file if BackupDir isn't set. If BackupDir is set we would rather have the old file + // put in the BackupDir than deleted which is what will happen if we don't delete it. + if fs.Config.BackupDir == "" { + err = dst.Remove() + if err != nil { + fs.Errorf(dst, "failed to delete before re-upload: %v", err) + } } return false } else if err != nil { diff --git a/lib/rest/rest.go b/lib/rest/rest.go index e536f0b89..3403e4155 100644 --- a/lib/rest/rest.go +++ b/lib/rest/rest.go @@ -246,7 +246,12 @@ func (api *Client) Call(opts *Opts) (resp *http.Response, err error) { } if !opts.IgnoreStatus { if resp.StatusCode < 200 || resp.StatusCode > 299 { - return resp, api.errorHandler(resp) + err = api.errorHandler(resp) + if err.Error() == "" { + // replace empty errors with something + err = errors.Errorf("http error %d: %v", resp.StatusCode, resp.Status) + } + return resp, err } } if opts.NoResponse {