javascript全局错误捕获需组合window.onerror(同步及异步js执行错误)、unhandledrejection(未处理promise拒绝)和error事件(资源加载失败),并配合框架钩子才能全覆盖。

JavaScript 中的全局错误捕获不能靠单一手段覆盖所有场景。真正有效的方案,是根据错误发生时机和执行上下文,选择或组合使用 window.onerror 和 window.addEventListener('unhandledrejection') 这两类机制——它们不是替代关系,而是分工明确的互补关系。
同步与异步运行时错误:onerror 的覆盖范围
window.onerror 是最基础的兜底机制,适用于 JS 执行阶段抛出的未被捕获错误:
- 能捕获顶层同步错误(如
undefined.xxx、throw new Error()) - 能捕获定时器、事件回调等异步上下文中的同步错误(如
setTimeout(() => { foo(); })) - 能捕获脚本加载失败(需
<script crossorigin></script>+ 服务端 CORS 头配合) - 对跨域脚本,默认只报
"Script error.",无行列号和错误对象,必须加crossorigin才能获取完整信息 - 不捕获 Promise 拒绝、ESM 静态导入失败、网络请求异常、DOM 渲染错误等非 JS 执行错误
Promise 拒绝错误:unhandledrejection 的专属职责
unhandledrejection 专门用于监听未被处理的 Promise 拒绝,和 onerror 完全不重叠:
- 只响应
Promise.reject()或async函数中throw但未被.catch()或try/catch捕获的情况 - 静态
import失败(如 404、MIME 错误)不会触发它;只有import()动态导入失败才会触发 - 事件回调里返回的 Promise(如
button.onclick = () => fetch().then(...))若拒绝且未处理,也会触发 - 它拿到的是
event.reason,通常为Error实例或任意 reject 值,但没有行列号等源码定位信息
资源加载失败:error 事件的不可替代性
window.addEventListener('error')(注意不是 onerror)负责捕获资源加载类错误,这是另一体系:
- 能监听
<img src="xxx">、<script src="xxx"></script>、<link href="xxx">等标签加载失败 - 错误不冒泡到
window.onerror,必须单独监听 - 可结合
event.target类型判断错误来源(如instanceof HTMLImageElement) - 对 ESM 模块加载失败(
<script type="module"></script>),它是比onerror更可靠的捕获入口
框架层错误:独立于原生机制之外
React、Vue 等框架在自身生命周期中拦截并封装了部分错误,原生全局监听可能失效:
- React 组件渲染异常由 Error Boundary 捕获,不会透出到
onerror - Vue 组件内同步错误被
Vue.config.errorHandler拦截,onerror默认收不到 - 框架内部异步操作(如 Vue 的 watch 回调、React 的 useEffect 中 Promise)仍可能触发
unhandledrejection - 要完整覆盖,需将框架提供的钩子(如
errorCaptured、componentDidCatch)与原生事件联合上报











