accounting: Correct exitcode on Transfer Limit Exceeded flag. Fixes #3203

Before this change the exit code for transfer limit exceeded was
incorrect. This was because the `resolveExitCode` function unwraps the
error thus reading the underlying error which is not the same as the
error it was comparing to (`ErrorMaxTransferLimitReached`).

This change fixes it by splitting the error definition in two so that
when the Fatal error is unwrapped we match against
`ErrorMaxTransferLimitReached` however when we return the error we
return `ErrorMaxTransferLimitReachedFatal`.
This commit is contained in:
Anuar Serdaliyev 2020-03-10 13:00:10 +01:00 committed by GitHub
parent 132ce94139
commit f14871caf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 10 additions and 6 deletions

View File

@ -16,9 +16,13 @@ import (
"github.com/rclone/rclone/fs/fserrors" "github.com/rclone/rclone/fs/fserrors"
) )
// ErrorMaxTransferLimitReached is returned from Read when the max // ErrorMaxTransferLimitReached defines error when transfer limit is reached.
// Used for checking on exit and matching to correct exit code.
var ErrorMaxTransferLimitReached = errors.New("Max transfer limit reached as set by --max-transfer")
// ErrorMaxTransferLimitReachedFatal is returned from Read when the max
// transfer limit is reached. // transfer limit is reached.
var ErrorMaxTransferLimitReached = fserrors.FatalError(errors.New("Max transfer limit reached as set by --max-transfer")) var ErrorMaxTransferLimitReachedFatal = fserrors.FatalError(ErrorMaxTransferLimitReached)
// Account limits and accounts for one transfer // Account limits and accounts for one transfer
type Account struct { type Account struct {
@ -172,7 +176,7 @@ func (acc *Account) checkRead() (err error) {
acc.statmu.Lock() acc.statmu.Lock()
if acc.max >= 0 && acc.stats.GetBytes() >= acc.max { if acc.max >= 0 && acc.stats.GetBytes() >= acc.max {
acc.statmu.Unlock() acc.statmu.Unlock()
return ErrorMaxTransferLimitReached return ErrorMaxTransferLimitReachedFatal
} }
// Set start time. // Set start time.
if acc.start.IsZero() { if acc.start.IsZero() {

View File

@ -219,7 +219,7 @@ func TestAccountMaxTransfer(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
n, err = acc.Read(b) n, err = acc.Read(b)
assert.Equal(t, 0, n) assert.Equal(t, 0, n)
assert.Equal(t, ErrorMaxTransferLimitReached, err) assert.Equal(t, ErrorMaxTransferLimitReachedFatal, err)
assert.True(t, fserrors.IsFatalError(err)) assert.True(t, fserrors.IsFatalError(err))
fs.Config.CutoffMode = fs.CutoffModeSoft fs.Config.CutoffMode = fs.CutoffModeSoft

View File

@ -364,7 +364,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj
actionTaken = "Copied (server side copy)" actionTaken = "Copied (server side copy)"
if fs.Config.MaxTransfer >= 0 && (accounting.Stats(ctx).GetBytes() >= int64(fs.Config.MaxTransfer) || if fs.Config.MaxTransfer >= 0 && (accounting.Stats(ctx).GetBytes() >= int64(fs.Config.MaxTransfer) ||
(fs.Config.CutoffMode == fs.CutoffModeCautious && accounting.Stats(ctx).GetBytesWithPending()+src.Size() >= int64(fs.Config.MaxTransfer))) { (fs.Config.CutoffMode == fs.CutoffModeCautious && accounting.Stats(ctx).GetBytesWithPending()+src.Size() >= int64(fs.Config.MaxTransfer))) {
return nil, accounting.ErrorMaxTransferLimitReached return nil, accounting.ErrorMaxTransferLimitReachedFatal
} }
if doCopy := f.Features().Copy; doCopy != nil && (SameConfig(src.Fs(), f) || (SameRemoteType(src.Fs(), f) && f.Features().ServerSideAcrossConfigs)) { if doCopy := f.Features().Copy; doCopy != nil && (SameConfig(src.Fs(), f) || (SameRemoteType(src.Fs(), f) && f.Features().ServerSideAcrossConfigs)) {
in := tr.Account(nil) // account the transfer in := tr.Account(nil) // account the transfer

View File

@ -1811,7 +1811,7 @@ func TestAbort(t *testing.T) {
accounting.GlobalStats().ResetCounters() accounting.GlobalStats().ResetCounters()
err := Sync(context.Background(), r.Fremote, r.Flocal, false) err := Sync(context.Background(), r.Fremote, r.Flocal, false)
expectedErr := fserrors.FsError(accounting.ErrorMaxTransferLimitReached) expectedErr := fserrors.FsError(accounting.ErrorMaxTransferLimitReachedFatal)
fserrors.Count(expectedErr) fserrors.Count(expectedErr)
assert.Equal(t, expectedErr, err) assert.Equal(t, expectedErr, err)
} }