es6 承诺吞下类型错误

Posted

技术标签:

【中文标题】es6 承诺吞下类型错误【英文标题】:es6 promises swallow type errors 【发布时间】:2016-01-27 08:32:59 【问题描述】:

我希望浏览器在发生类型错误时显示错误消息。can not read property something of undefinedundefined reference 等错误。

new Promise(function(resolve,reject)
    // do stuff ...
    reject('something logical is wrong');
).catch(e => console.error(e));

new Promise(function(resolve,reject)
    // do stuff, and a syntax error :/
    var a =  ;
    a.something.otherthing = 1; /* we have an error here */
    // ... 
).catch(e => console.error(e));

在第一个示例中,错误是一个逻辑错误,可以在 catch(..) 块中catch。 但在第二个例子中,这是一个明显的开发错误,在开发新东西时一直发生。我不想抓住它,我希望浏览器像控制台中的其他错误一样向我显示错误。 我希望能够打开 chrome pause on exceptions 并查看其他变量的状态。我想在控制台中查看堆栈跟踪。 我希望它表现得像一个正常错误。

有什么想法吗?

【问题讨论】:

使用您的第二个示例,我在控制台TypeError: Cannot set property 'otherthing' of undefined 中收到以下错误。这不是你想要发生的吗?承诺未决,但这是一个不同的问题。 我想要错误的行号,堆栈跟踪。 @AdamJeffers 我也想使用 chrome 打破异常功能。 要获得正确的错误行号,我认为您需要删除 catch()?这是一个有趣的问题,我觉得有必要进一步调查! FWIW 与您的示例一样,我在 Chrome 和 Firefox 的控制台中都获得了 TypeError 的行号,在 Firefox 中,我还在控制台中获得了堆栈跟踪。 【参考方案1】:

与同步代码中的异常不同,一旦代码返回到idle,异常就会未捕获,浏览器通常不知道promise-chain的逻辑结束,这就是 异步错误 可能被视为未捕获的地方。毕竟链是动态组装的,因此最好在链的逻辑末端使用最终的.catch 终止,即空闲的异步等价物。

拥有一个最终的.catch(e => console.error(e)) 对我来说似乎很合理,但你说得对,浏览器倾向于以不同于未捕获异常的方式显示这些错误。如果你想让它们看起来一样,你可以使用这个技巧:

.catch(e => setTimeout(() =>  throw e; ))

这将在下一个循环中抛出包含原始堆栈跟踪和行号的e,并且在承诺链之外,没有任何东西可以捕获它,它会被报告为未捕获。我们使用setTimeout 来克服.catch 的默认行为,即在您打算继续链接时捕获链中的任何异常。

有了这个,我希望你看到“逻辑”和其他错误之间的任何区别都是无关紧要的。任何导致链尾的错误对链来说都是致命的,即未捕获(当然,如果你选择,你可以从最终捕获的其他错误中对“逻辑”进行分类,并以不同的方式显示它们。 )

【讨论】:

【参考方案2】:

chromeSources 选项卡中有一个选项Pause on Caught Exceptions,我启用了该选项并Pause on Exceptions 功能现在运行良好。

【讨论】:

这将暂停逻辑错误和TypeError,因此这似乎不符合您自己问题的标准。

以上是关于es6 承诺吞下类型错误的主要内容,如果未能解决你的问题,请参考以下文章

错误:`未捕获(承诺中)类型错误:无法读取未定义的属性'doc'`

使用 fetch 和 ES6 承诺处理自定义错误的最简洁方法

错误:未捕获(承诺中)类型错误:n.swapComponent 不是函数

错误::未捕获(承诺中)类型错误:无法读取未定义的属性“内容”

未捕获(承诺)类型错误:尝试打开窗口时出现问题

Axios 承诺处理 - 在 react-native 中获取“可能的未处理承诺拒绝 - 类型错误:网络请求失败”