window.onerror可捕获setTimeout、事件回调等异步运行时错误,但无法捕获Promise拒绝异常,后者需通过unhandledrejection事件监听;资源加载错误则需单独监听error事件。

window.onerror 本身就能捕获异步运行时错误,比如 setTimeout、setInterval、事件回调中抛出的 ReferenceError 或 TypeError。但它不负责捕获 Promise 拒绝(reject)类的异步异常——这类错误必须靠 unhandledrejection 事件单独监听。
onerror 能捕获哪些异步错误
只要错误是「同步执行路径之外、但仍是 JS 运行时抛出的错误」,window.onerror 就能收到:
-
setTimeout(() => { foo.bar(); }, 100)—— 访问 undefined 属性 document.body.addEventListener('click', () => { throw new Error('boom') })requestAnimationFrame(() => { notExist() })
这些都会触发 onerror 回调,并传入完整的 error 对象(含堆栈)。
为什么 Promise 错误不能靠 onerror 捕获
Promise 的 reject 不会直接触发 JS 运行时错误,它只是让 Promise 进入 rejected 状态。只有当这个状态未被 .catch() 或 await 处理时,浏览器才在微任务末尾派发 unhandledrejection 事件——这和 onerror 的错误机制完全独立。
- ✅ 正确监听方式:
window.addEventListener('unhandledrejection', e => { console.log(e.reason) }) - ❌ 错误依赖:
window.onerror对Promise.reject(new Error(...))无响应
实际部署建议
要真正覆盖异步异常,需组合使用两个监听器,并注意顺序与返回值:
-
window.onerror放在所有脚本最顶部,且函数体末尾 显式返回true,防止错误继续冒泡到控制台 -
unhandledrejection同样建议加e.preventDefault(),避免默认行为干扰 - 对资源加载失败(如图片 404、script 加载失败),需单独监听
error事件(如document.addEventListener('error', handler, true))
典型遗漏点
很多项目只配了 onerror,却没加 unhandledrejection,导致 axios 请求失败、fetch().then() 中抛错、Vue 组件内 async mounted 出错等场景全部漏报。这类问题在线上静默发生,用户白屏或功能失效,但监控平台毫无记录。











