diff --git a/internal/backend/backend_retry.go b/internal/backend/backend_retry.go index fe0d34799..fea0714a9 100644 --- a/internal/backend/backend_retry.go +++ b/internal/backend/backend_retry.go @@ -32,6 +32,25 @@ func NewRetryBackend(be restic.Backend, maxTries int, report func(string, error, } } +// retryNotifyErrorWithSuccess is an extension of backoff.RetryNotify with notification of success after an error +// success is NOT notified on the first run of operation (only after an error) +func retryNotifyErrorWithSuccess(operation backoff.Operation, b backoff.BackOff, notify backoff.Notify, success func()) error { + if success == nil { + return backoff.RetryNotify(operation, b, notify) + } + errorDetected := false + operationWrapper := func() error { + err := operation() + if err != nil { + errorDetected = true + } else if errorDetected { + success() + } + return err + } + return backoff.RetryNotify(operationWrapper, b, notify) +} + func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) error { // Don't do anything when called with an already cancelled context. There would be // no retries in that case either, so be consistent and abort always.