Skip to content

Abort every in-flight chunk when a chunked upload is canceled - #2371

Open
enyo wants to merge 1 commit into
mainfrom
cancel-parallel-chunks
Open

Abort every in-flight chunk when a chunked upload is canceled#2371
enyo wants to merge 1 commit into
mainfrom
cancel-parallel-chunks

Conversation

@enyo

@enyo enyo commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Fixes #2366.

The bug

_uploadData stores its request on the file:

for (let file of files) {
  file.xhr = xhr;
}

With parallelChunkUploads that runs once per concurrent chunk, so file.xhr ends up holding whichever request started last. cancelUpload aborts only that one:

if (typeof file.xhr !== "undefined") {
  file.xhr.abort();
}

Cancel a 3-way parallel chunked upload and two of the three requests keep streaming to the server. They are silent about it: files[0].status is already CANCELED, so _finishedUploading and _handleUploadError both return early and nothing is emitted. The user's bandwidth keeps going, and the server keeps receiving chunks for a file the UI says was canceled. Worse, if that last chunk had already completed, file.xhr points at a finished request and abort() does nothing at all while the others are still live.

The fix

Each chunk already carries its own xhr (file.upload.chunks[i].xhr, set in _uploadData and cleared on success), so cancelUpload walks the chunks and aborts the ones still UPLOADING, marking them CANCELED. Non-chunked uploads keep aborting file.xhr exactly as before.

Test

should abort every chunk still in flight when the upload is canceled starts a 6-chunk upload with parallelChunkUploads: 3 and cancels it. Against main the assertion reads expected [ false, false, true ] to deeply equal [ true, true, true ] — the reported behaviour, exactly.

One thing I noticed but did not touch

cancelUpload opens with this._getFilesWithXhr(file.xhr!). When a file is canceled during the _transformFiles window it is already UPLOADING but has no xhr yet, so that call matches every file whose xhr is still undefined — i.e. every queued file — and marks them all CANCELED with a canceled event each. That is a separate bug from the one reported here, so I left it alone; happy to do it in its own PR.

`cancelUpload` aborted `file.xhr`, which only ever holds the request that
started last. With `parallelChunkUploads` the other chunks kept streaming
to the server for a file the UI already showed as canceled, and if the
last chunk had finished, `file.xhr` pointed at a completed request and
the abort did nothing at all.

Each chunk already carries its own `xhr`, so walk `file.upload.chunks`
and abort the ones still uploading. Non-chunked uploads keep aborting
`file.xhr` as before.

Fixes #2366

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 79.51% 885 / 1113
🔵 Statements 79.86% 932 / 1167
🔵 Functions 92.89% 196 / 211
🔵 Branches 76.77% 519 / 676
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/dropzone/src/dropzone.ts 77.52% 75.26% 92.63% 77.04% 233, 243, 268, 274-277, 334, 361, 404-405, 464, 572, 594, 613-614, 721, 744-747, 784-786, 816-819, 842, 988, 1016, 1045, 1049, 1121-1122, 1154, 1164-1166, 1183-1184, 1190-1223, 1348, 1406, 1455-1456, 1584, 1608-1609, 1663, 1697, 1717-1748, 1756, 1770-1774, 1785, 1798-1803, 1816-1817, 1821-1822, 1840-1841, 1919-1934, 1979, 1995, 2166-2168, 2203, 2213, 2246-2280, 2287-2388, 2397-2400
Generated in workflow #140 for commit 536d94a by the Vitest Coverage Report Action

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.

cancelUpload() Fails to Abort In-Flight Requests When parallelChunkUploads is Enabled

1 participant