Skip to content

fix(lib-storage): pass abortSignal to single-part PutObject (#5109) - #7992

Open
mohanrajvenkatesan23-04 wants to merge 1 commit into
aws:mainfrom
mohanrajvenkatesan23-04:fix/issue-5109-lib-storage-single-part-abort
Open

fix(lib-storage): pass abortSignal to single-part PutObject (#5109)#7992
mohanrajvenkatesan23-04 wants to merge 1 commit into
aws:mainfrom
mohanrajvenkatesan23-04:fix/issue-5109-lib-storage-single-part-abort

Conversation

@mohanrajvenkatesan23-04

Copy link
Copy Markdown

Issue

Fixes #5109

Description

lib-storage's Upload exposes an abort() method backed by an internal AbortController. For multipart uploads this controller is wired into the UploadPartCommand / CreateMultipartUploadCommand calls, so calling upload.abort() mid-flight cancels the in-flight HTTP requests.

For the single-part path (__uploadUsingPut, around line 168 of Upload.ts), however, the underlying call was:

this.client.send(new PutObjectCommand(params))

with no second argument. As a result, calling upload.abort() mid-flight caused done() to reject (via the existing Promise.race against __abortTimeout(this.abortController.signal)), but the in-flight HTTP PUT continued to completion and the file was still written to S3 — exactly the bug reported in #5109.

This PR passes the standard SDK option { abortSignal: this.abortController.signal } as the second argument to client.send(...) in __uploadUsingPut, so the in-flight PUT is cancelled at the HTTP layer when the user calls upload.abort(). Net production diff is 4 lines and reuses the controller already present on the class.

Files changed:

  • lib/lib-storage/src/Upload.ts (+4 net lines) — pass abortSignal through to client.send.
  • lib/lib-storage/src/Upload.spec.ts (+~56 lines) — two regression tests, see Testing.

Testing

Two regression tests added in lib/lib-storage/src/Upload.spec.ts:

  1. should pass abortSignal to client.send for single-part (PutObject) uploads (#5109) — directly asserts client.send is invoked with { abortSignal } matching the upload's controller. Pre-fix this test fails (the second arg was undefined); post-fix it passes.
  2. should abort an in-flight single-part (PutObject) upload (#5109) — uses a mocked client.send that resolves only when its abortSignal is aborted. After abortController.abort() is called mid-flight, asserts upload.done() rejects with name: "AbortError". This is the user-observable behavior the reporter wanted.

Local verification:

  • tsc --noEmit -p tsconfig.json introduces zero new errors versus baseline.
  • Running Vitest locally for lib/lib-storage is blocked by a pre-existing workspace-build / Yarn-on-Windows-with-spaces issue (workspace dist-*/ not built locally and unrelated @aws-sdk/client-s3 module-resolution warnings), so test execution is being deferred to CI, which will validate both the new tests and the existing suite.

Checklist

  • If the PR is a feature, add integration tests (*.integ.spec.ts) or E2E tests.
    • It's not a feature.
  • My E2E tests are resilient to concurrent i/o.
    • I didn't write any E2E tests.
  • I added access level annotations e.g. @public, @internal tags and enabled doc generation on the package. Remember that access level annotations go below the description, not above.
    • I didn't add any public functions.
  • Streams - how do they work?? My WebStream readers/locks are properly lifecycled. Node.js stream backpressure is handled. Error handling.
    • No streams here.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

generated by AI tools, and reviewed by Mohanraj Venkatesan

When lib-storage's Upload falls into the single-part path
(__uploadUsingPut), the underlying client.send(new PutObjectCommand(...))
call did not forward the upload's abortController.signal. Calling
upload.abort() mid-flight caused done() to reject (via the existing
Promise.race against __abortTimeout), but the in-flight HTTP PUT
continued to completion and the file was still written to S3.

Pass { abortSignal: this.abortController.signal } as the second
argument to client.send(...) so the in-flight PUT is cancelled at the
HTTP layer when the user calls upload.abort(), matching the behavior
already wired up for the multipart path.

Fixes aws#5109
@mohanrajvenkatesan23-04
mohanrajvenkatesan23-04 requested a review from a team as a code owner May 6, 2026 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(lib-storage): single-part uploads not really abortable

1 participant