streams
streams copied to clipboard
Should cancelation error from UnderlyingSource be transferred too?
b = new ReadableStream({
cancel() {
throw new Error("Hello");
}
})
transferred = structuredClone(b, { transfer: [b] })
// This resolves as it never gets the error message back, with its port immediately closed
transferred.cancel();
Couldn't find a relevant discussion, but WPT explicitly tests it to not wait for the underlying source cancel. What was the reason behind it?
I don't have a good argument against the current behavior, just out of curiosity.
The short answer is that it's because transferable streams are implemented using a pipe, and pipes propagate cancellation without waiting.
Elaborating a bit, what we have is
original ---pipe---> writable <==CRIT==> transferred
(where "CRIT" means cross-realm identity transform). The internal pipe is invisible to developers, except to the extent that it dictates the semantics.
When transferred is cancelled, this is propagated back by erroring writable. Erroring is a synchronous operation, so there's no opportunity to wait.
When the pipe sees the writable is errored, it propagates it back by cancelling the original stream. Because writable is already errored, the results of cancellation cannot be propagated back up the pipe.
See also https://github.com/whatwg/streams/issues/976.