When calling ReadableStreamDefaultController.error or TransformStreamDefaultController.error
with an Error object to manually error out a stream, the error is logged in the browser console, at the site of invocation, as an uncaught error, as if the .error()
method itself was re-throwing the error it was fed.
The following short snippet with a ReadableStream source and WritableStream destination showcases the issue, however, it seems the stackoverflow snippet console fails to log the error (check the browser console, on Chrome 80):
let sourceController;
let source = new ReadableStream({
start: (controller) => {
sourceController = controller;
}
});
let destination = new WritableStream({
start: () => {
// ...
},
abort: (reason) => {
console.log("aborted:");
console.log(reason);
}
});
source.pipeTo(destination);
window.setTimeout(() => sourceController.error(new Error("wut?")), 1000);
// ^^^^^
// js:30 Uncaught (in promise) Error: wut?
Judging by the error message, this may be a rejected promise somewhere, but I have no idea where. Strangely, trying to observe this uncaught error using the following listener has no effect either:
window.onerror = (e) => console.error(e); // Never gets called
I would've thought defining the abort
method on the destination WritableStream marks that the stream is enabled with error handling, yet the error is still logged as an uncaught error (strangely, the abort
method is called at the same time).
To me it seems this error is completely harmless, but it sure is annoying.
How do I get rid of it? Adding a try ... catch
around the thing doesn't do anything.
The error is originating from the Promise returned by the pipeTo
call, because erroring out the stream will reject this Promise. The solution is to add the missing catch clause:
source.pipeTo(destination).catch(err => ...)
Or, in an async
execution context:
try {
await source.pipeTo(destination);
} catch (err) {
...
}
This is explained in the WHATWG Streams spec:
An error in the source readable stream will abort the destination writable stream, unless preventAbort is truthy. The returned promise will be rejected with the source’s error, or with any error that occurs during aborting the destination.