fix: emit final 100% download progress for empty response body
onDownloadProgress never fired a completion event when the response body was empty (e.g. a 200 with Content-Length: 0), since the final callback in the transform stream's flush() was gated behind a chunk having been read. Report the final progress unconditionally, falling back to an empty chunk when the stream produced none. Closes #878
This commit is contained in:
1 parent
ee0d0d0437
commit
1cf8f269f3
2 files changed
+23
-1
No files matched your search
@@ -70,8 +70,10 @@ const withProgress = (stream: ReadableStream<Uint8Array>, totalBytes: number, on
|
|||||||
flush() {
|
flush() {
|
||||||
if (previousChunk) {
|
if (previousChunk) {
|
||||||
transferredBytes += previousChunk.byteLength;
|
transferredBytes += previousChunk.byteLength;
|
||||||
onProgress?.({percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes}, previousChunk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always report completion, even for an empty stream, so consumers can rely on a final 100% event.
|
||||||
|
onProgress?.({percent: 1, totalBytes: Math.max(totalBytes, transferredBytes), transferredBytes}, previousChunk ?? new Uint8Array());
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -555,6 +555,26 @@ test('onDownloadProgress cancels original response body', async t => {
|
|||||||
t.true(didReportProgress);
|
t.true(didReportProgress);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('onDownloadProgress emits final 100% progress for empty response body', async t => {
|
||||||
|
const server = await createHttpTestServer(t);
|
||||||
|
server.get('/', (_request, response) => {
|
||||||
|
response.status(200).end();
|
||||||
|
});
|
||||||
|
|
||||||
|
const progressEvents: Progress[] = [];
|
||||||
|
await ky(server.url, {
|
||||||
|
onDownloadProgress(progress) {
|
||||||
|
progressEvents.push(progress);
|
||||||
|
},
|
||||||
|
}).text();
|
||||||
|
|
||||||
|
t.true(progressEvents.length > 0, 'Should emit at least one progress event');
|
||||||
|
const finalProgress = progressEvents.at(-1);
|
||||||
|
t.truthy(finalProgress);
|
||||||
|
t.is(finalProgress!.percent, 1);
|
||||||
|
t.is(finalProgress!.transferredBytes, finalProgress!.totalBytes);
|
||||||
|
});
|
||||||
|
|
||||||
test('forced retry custom request keeps upload progress', async t => {
|
test('forced retry custom request keeps upload progress', async t => {
|
||||||
const server = await createHttpTestServer(t, {bodyParser: false});
|
const server = await createHttpTestServer(t, {bodyParser: false});
|
||||||
let requestCount = 0;
|
let requestCount = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user