1

当调用ReadableStreamDefaultController.errorTransformStreamDefaultController.error使用 Error 对象手动错误输出流时,错误会在调用站点的浏览器控制台中记录为未捕获的错误,就好像.error()方法本身正在重新抛出错误一样喂。

以下带有 ReadableStream 源和 WritableStream 目标的简短片段展示了该问题,但是,stackoverflow 片段控制台似乎无法记录错误(检查浏览器控制台,在 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?

从错误信息来看,这可能是某处被拒绝的承诺,但我不知道在哪里。奇怪的是,尝试使用以下侦听器观察这个未捕获的错误也没有效果:

window.onerror = (e) => console.error(e); // Never gets called

我会考虑abort在目标 WritableStream 上定义该方法标记该流已启用错误处理,但该错误仍被记录为未捕获的错误(奇怪的是,该abort方法同时被调用)。

对我来说,这个错误似乎完全无害,但确实很烦人。

我该如何摆脱它?在事物周围添加 atry ... catch不会做任何事情。

4

1 回答 1

1

错误源于pipeTo调用返回的 Promise,因为错误输出流将拒绝此 Promise。解决方案是添加缺少的 catch 子句:

source.pipeTo(destination).catch(err => ...)

或者,在async执行上下文中:

try {
    await source.pipeTo(destination);
} catch (err) {
    ...
}

这在WHATWG Streams 规范中进行了解释:

源可读流中的错误将中止目标可写流,除非 preventAbort 为真。返回的 Promise 将因源错误或在中止目标期间发生的任何错误而被拒绝。

于 2020-02-20T15:48:07.397 回答