监听 window.onerror 为啥收不到异步错误?
我在项目里加了全局错误监控,用的是 window.onerror,同步的报错都能捕获到,但像 setTimeout 里的错误就收不到了,这是为啥?
我试过这样写:
window.onerror = function(msg, url, line, col, error) {
console.log('捕获到错误:', error);
return true;
};
setTimeout(() => {
throw new Error('异步错误测试');
}, 100);
结果控制台报错了,但 onerror 根本没触发,是不是异步错误得用别的方法监听?
window.onerror对异步代码(setTimeout、Promise等)的捕获能力确实有限,不同浏览器表现还不一样。直接说结论:用
window.addEventListener('error')配合window.addEventListener('unhandledrejection')才是正解。代码给你:
说下区别在哪。用
window.onerror = function的方式其实是在覆盖 onerror 属性,只能绑定一个处理函数,而且某些场景下事件对象信息不全。用addEventListener可以绑定多个监听,事件对象里信息更完整,对异步错误的支持也更稳定。另外要注意,如果你的 JS 文件是跨域加载的,记得给 script 标签加
crossorigin属性,否则错误信息会被浏览器吃掉,只能拿到Script error.这种没用的提示,这个坑踩的人特别多。要捕获异步错误,得用 window.addEventListener('error', handler, true),而且得用捕获阶段(第三个参数设为 true),因为冒泡阶段的 error 事件在 window 层级可能已经被拦截或丢失了。
你改成这样试试:
注意,Promise 的 unhandledrejection 得单独监听 window.onunhandledrejection 或 addEventListener('unhandledrejection'),这个跟 error 事件是两套体系,别混了。
对了,IE 里老版本不支持 addEventListener,但那会儿也基本没人用 window.onerror 做监控了,现在基本都是现代浏览器,放心用 addEventListener('error', ..., true) 就行。