Skip to content

s3: cancellation not detected and not aborted in S3 operations #492

Description

@parikshithb

Problem

When the user cancels an operation (Ctrl+C), S3 operations have two issues:

  1. 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.

  2. 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)
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions