fix(session-export): propagate download cancellation

Only the root raw-artifact read received the request signal. Lineage discovery and descendant reads could continue after disconnect, response-body cancellation did not stop the producer, and the root error boundary converted an abort rejection into an ordinary HTTP 500.

Combine request and response-consumer cancellation into the ZIP producer signal, forward it through every cancellable read, check it around the attachment seam, and terminate fflate exactly once when production stops. The pre-stream boundary now rethrows the original abort instead of translating it. Regression tests cover signal propagation, exact cancellation identity at the HTTP boundary, and a reader cancellation interrupting an in-flight descendant read; the bilingual host contract records these lifecycle semantics.
This commit is contained in:
Tianyi Cui
2026-08-11 15:14:10 +08:00
parent 52f0b09e76
commit 192840e198
9 changed files with 176 additions and 24 deletions

View File

@@ -3506,7 +3506,9 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
try {
await flushLiveSessionLog(deps, request.sessionId, signal)
root = await deps.sessionPersistence.readRaw(request.sessionId, signal)
signal.throwIfAborted()
} catch {
signal.throwIfAborted()
// Backend read failure: answer 500 without echoing the error, which
// may carry absolute host paths into the browser error bar.
return new Response('session log export failed to read the stored artifact', { status: 500 })