phi*_*294 9 javascript stack-trace promise
当我只使用处理程序捕获 Promise 拒绝时,如何确定发生在哪里onunhandledrejection?
console.error = ()=>{}\nwindow.addEventListener(\'unhandledrejection\', (promiseRejectionEvent) => {\n console.log(\'unhandled: \', Error().stack)\n})\n\nfunction main() {\n new Promise(() => { throw null })\n}\nmain()Run Code Online (Sandbox Code Playgroud)\r\n如果运行此命令后检查浏览器的控制台,您将看到类似以下内容的内容:
\n
\n
唯一Error().stack的在其堆栈跟踪中包含拒绝处理程序函数本身(灰色输出js:14:30)。但浏览器似乎确实知道拒绝发生在哪里:还有另一个红色错误输出(Uncaught (in promise) null),指向目标行(js:18)。如何获取该线路信息?
后一个输出似乎是由浏览器的内部完成的,因为它无法通过console.error像上面的示例中那样的覆盖来防止。正如MDNpromiseRejectionEvent.preventDefault()上所解释的,只能通过调用来防止这种情况。但我无论如何都不想阻止它,而是检索它,例如用于记录目的。
现实世界用例:当然可以不依赖onunhandledrejection事件处理程序,例如通过添加.catch()短语或至少抛出throw new Error(null)。但就我而言,我无法控制它,因为它是第三方代码。今天它在客户端浏览器上意外抛出(可能是库错误),并且自动错误报告不包含堆栈跟踪。我试图缩小上述根本问题的范围。谢谢!
编辑回应评论:
\n\n\n将第三方代码包装在 try/catch 中?\xe2\x80\x93 世界
\n
好点,但这没有帮助,因为拒绝实际上发生在回调内:
\nwindow.addEventListener(\'unhandledrejection\', (promiseRejectionEvent) => {\n console.log(\'unhandled: \', Error().stack) // <- stack once again does *not* include "main()", it is only printed out in the console\n})\n\nfunction main() {\n try {\n thirdPartyModule()\n } catch(e) {\n // Never caught\n console.log("caught:", e)\n }\n}\n\n// Example code\n// We cannot change this function\nfunction thirdPartyModule() {\n setTimeout(() =>\n new Promise(() =>\n { throw null }))\n}\n\nmain()Run Code Online (Sandbox Code Playgroud)\r\n小智 4
免责声明:使用此解决方法对于调试很有用,但会对性能产生轻微的负面影响,并可能导致各种库行为不当;它不应该在生产代码中使用。
您可以将 Promise 构造函数替换为您自己的实现,其中包含创建它的堆栈跟踪。
window.Promise = class FAKEPROMISE extends Promise {
constructor() {
super(...arguments);
this.__creationPoint = new Error().stack;
}
};
Run Code Online (Sandbox Code Playgroud)
这将为您提供创建任何给定承诺的点的堆栈跟踪。请注意.then,.catch、 和.finally都创建了新的 Promise。
这不适用于async函数创建的 Promises,因为它们不使用窗口的Promise构造函数。
promise这可以通过阅读以下成员来使用PromiseRejectionEvent:
window.addEventListener('unhandledrejection', (promiseRejectionEvent) => {
console.log('unhandled: ', promiseRejectionEvent.promise.__creationPoint)
})
Run Code Online (Sandbox Code Playgroud)
这将打印类似的内容:
unhandled: Error
at new FAKEPROMISE (script.js:4:32)
at main (script.js:6:3)
at script.js:9:1
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3221 次 |
| 最近记录: |