【问题标题】:Manually erroring out a ReadableStream or TransformStream causes the error to be logged as an uncaught error手动出错 ReadableStream 或 TransformStream 会导致错误被记录为未捕获的错误
【发布时间】:2020-05-27 05:40:35
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: javascript whatwg-streams-api


    【解决方案1】:

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

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

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

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

    这在WHATWG Streams spec中有解释:

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

    【讨论】:

      猜你喜欢
      • 2016-10-28
      • 2023-03-28
      • 1970-01-01
      • 2017-05-19
      • 2020-10-31
      • 2020-07-28
      • 1970-01-01
      • 2018-04-23
      • 2016-02-27
      相关资源
      最近更新 更多