Repository navigation
fix(dashboard): await upload status before parsing the resume response - #10534
Open
dafyy321-pixel wants to merge 1 commit into
Open
dafyy321-pixel wants to merge 1 commit into
dafyy321-pixel wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
Hey - I've reviewed your changes and they look great!
Sourcery assessment
Needs a human reviewer. If the awaited status response is interpreted incorrectly, resume could upload the wrong set of chunks or complete an incorrect upload, leaving bounded server-side upload data or an attachment behind. Reverting would stop the behavior but would not remove any chunks or completed attachment already written; those would need cleanup or a retry.
6 tasks done
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10533.
This makes
resume()await the upload-status request before parsing the response. A valid session now keeps its upload ID and sends only the chunks the server has not received.Currently, a Promise is passed into the synchronous
envelopeData()helper. The outerawaitdoes not delay that helper call. The parser sees no response envelope, and the existing catch block clearsuploadIdas though the session were expired. The uploader then initializes another session and sends every chunk again, even if the original status request returns successfully.The production change is one line in the shared scheduler. It applies to both the backup dialog and chunked WebChat attachments.
Modifications
Await the status response at the point it is consumed
In
dashboard/src/composables/useChunkedUpload.ts, change:to:
statusUpload()is asynchronous;envelopeData()is synchronous. This order matches the composable's existing initialization, chunk-upload, and completion calls, which also await the endpoint response before parsing it.With the resolved envelope available,
received_chunksfeeds the existing progress calculation and missing-chunk filter. No new scheduling algorithm or state variable is needed.The same
try/catchstill handles an expired response or a rejected status request. In those cases, the existing fallback clears the upload ID, creates a fresh session, and uploads the full file. A rejected Promise is now awaited inside that handler rather than being passed to a parser that cannot observe its result.Exercise the actual composable in four resume scenarios
dashboard/tests/chunkedUploadResume.test.mjsimports the TypeScript source through the existing TypeScript/Vue dependencies and runs the actual composable. It uses Node's test runner and a realFile; the Vue refs and computed progress are part of the behavior under test.The fixture uses a 14-byte file divided into chunks of
4,4,4, and2bytes. It first leaves the uploader in a resumable state after the first 12 bytes have been accepted, then supplies each of the status scenarios below.0,1,2receivedsession-13, with a 2-byte payloadsession-1session-20,1,2,3session-20,1,2,3Each case checks the queried session ID, number of initialized sessions, uploaded chunk indices, upload destination, and completed session. The missing-chunk case also verifies that progress is restored to
12 / 14bytes and86%before the final chunk is uploaded.Completion verifies
14 / 14bytes and100%. The final assertions check that the attachment result is returned, status becomesdone, the error message is cleared, andcanResumebecomes false. The all-received case guards the useful edge where an interrupted client needs only to finalize the existing server-side transfer.Request sequence after the change
For a valid original session with one missing chunk:
There is one initialization across the original transfer and its resume. Previously received chunks do not consume another upload request, and progress reflects the server's existing data as soon as status is available.
For a session that genuinely needs replacement, the fallback still initializes a second session and completes a full upload. The four cases cover both paths rather than changing the valid-session path at the expense of recovery behavior.
Verification Steps and Test Results
Validated locally on Windows using Node.js
24.19.0, pnpm10.28.2, and Ruff0.15.22.Run from
dashboard/:The focused resume cases pass 4/4, and the dashboard Node tests pass 67/67. The production build includes
vue-tsc --noEmitand Vite; both completed successfully, with 5,668 modules transformed during bundling. The i18n check passed across four languages, each containing 4,130 keys, and checked 121 source files.Full-repository Ruff formatting and static analysis also passed.
git diff --checkis clean.Compatibility and review scope
Only the composable's status-parser line and the new regression file change. The tests use dependencies already in the dashboard; there are no package-manifest or lockfile changes.
The five upload API methods, request/response schemas, upload limits, concurrency limit, per-chunk retry count, cancellation handling, and server-side session lifetime remain as implemented. The change restores the existing same-page resume behavior while the composable still holds the file and session. It does not add persistence across a page reload.
No button labels, navigation, or page structure change, so the existing WebUI usage instructions and screenshots remain applicable. The backend upload routes and generated API client also remain the same.
This is separate from #10201's start/resume guards and #10427's backend assembly work. It corrects the order in which an existing frontend request is awaited and parsed.
Checklist
Summary by Sourcery
Fix chunked-upload resume processing and verify both session reuse and recovery paths.
Bug Fixes:
Tests: