filescom: fix corrupted uploads after a retried upload error

When an upload failed with a retryable error the pacer retried the
whole upload with the same input stream. The stream had already been
consumed by the first attempt so the retry uploaded an empty file.

This fixes it by using CallNoRetry for the upload, as the other
backends do, so retryable errors are returned wrapped in a RetryError
for the caller to retry the upload with a fresh stream.

It also makes 5xx errors from the upload storage servers retryable.
These come back from the SDK as a different error type to API errors
so were not being retried at all.
This commit is contained in:
Nick Craig-Wood
2026-09-05 12:14:46 +01:00
parent f4cd80a535
commit fa43f10af2
+9 -1
View File
@@ -19,6 +19,7 @@ import (
"github.com/Files-com/files-sdk-go/v3/file"
file_migration "github.com/Files-com/files-sdk-go/v3/filemigration"
"github.com/Files-com/files-sdk-go/v3/folder"
files_sdk_lib "github.com/Files-com/files-sdk-go/v3/lib"
"github.com/Files-com/files-sdk-go/v3/session"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
@@ -176,6 +177,13 @@ func shouldRetry(ctx context.Context, err error) (bool, error) {
}
}
// Errors from the upload storage servers are of this type
var httpErr files_sdk_lib.ResponseError
if errors.As(err, &httpErr) && slices.Contains(retryErrorCodes, httpErr.StatusCode) {
fs.Debugf(nil, "Retrying HTTP error %v", err)
return true, err
}
return fserrors.ShouldRetry(err), err
}
@@ -853,7 +861,7 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
file.UploadWithProvidedMtime(src.ModTime(ctx)),
}
err := o.fs.pacer.Call(func() (bool, error) {
err := o.fs.pacer.CallNoRetry(func() (bool, error) {
err := o.fs.fileClient.Upload(uploadOpts...)
return shouldRetry(ctx, err)
})