Problem
When the user cancels an operation (Ctrl+C), S3 operations have two issues:
-
Download loop not aborted on cancellation
In downloadObjects, when downloadObject fails due to cancellation, the loop increments failed and continues trying to download remaining objects — all of which will also fail. The function eventually returns "failed to download N of M objects" instead of a clean cancellation.
-
Cancellation not detected by callers
In downloadObjects, the listing error from NextPage does not preserve the cause. In checkBucket, the HeadBucket error also drops the cause. Since the errors are not preserved, downstream errors.Is(r.Err, context.Canceled) checks never match, and cancellation is misreported as a failure.
Proposed Solution
Use errors.Is(err, context.Canceled) on the AWS SDK error to detect cancellation (the AWS SDK wraps context.Canceled in its errors). On detection, return the error immediately:
Download loop abort on first cancellation
if err := s.downloadObject(ctx, *obj.Key, profileDir); err != nil {
if errors.Is(err, context.Canceled) {
return err
}
s.log.Warnf("Failed to download object %q from bucket %q: %v",
*obj.Key, s.profile.Bucket, err)
failed++
continue
}
NextPage error, return cancellation directly
if err != nil {
if errors.Is(err, context.Canceled) {
return err
}
s.log.Warnf("Failed to list objects in bucket %q with prefix %q: %v",
s.profile.Bucket, prefix, err)
return fmt.Errorf("failed to list objects in bucket %q with prefix %q",
s.profile.Bucket, prefix)
}
checkBucket, return cancellation directly
if err != nil {
if errors.Is(err, context.Canceled) {
return err
}
log.Warnf("Failed to access bucket %q for profile %q: %v",
profile.Bucket, profile.Name, err)
return fmt.Errorf("failed to access bucket %q for profile %q",
profile.Bucket, profile.Name)
}
Problem
When the user cancels an operation (Ctrl+C), S3 operations have two issues:
Download loop not aborted on cancellation
In downloadObjects, when downloadObject fails due to cancellation, the loop increments failed and continues trying to download remaining objects — all of which will also fail. The function eventually returns "failed to download N of M objects" instead of a clean cancellation.
Cancellation not detected by callers
In downloadObjects, the listing error from NextPage does not preserve the cause. In checkBucket, the HeadBucket error also drops the cause. Since the errors are not preserved, downstream errors.Is(r.Err, context.Canceled) checks never match, and cancellation is misreported as a failure.
Proposed Solution
Use errors.Is(err, context.Canceled) on the AWS SDK error to detect cancellation (the AWS SDK wraps context.Canceled in its errors). On detection, return the error immediately:
Download loop abort on first cancellation
NextPage error, return cancellation directly
checkBucket, return cancellation directly