window.onerror仅捕获js执行错误,无法监听资源加载失败;addeventlistener('error')可捕获js错误及img/script/link等资源加载失败,且支持捕获阶段介入;两者均无法捕获未处理的promise拒绝错误,需单独监听unhandledrejection事件。

识别两者的监控粒度,关键看能捕获什么错误、在哪一环节触发、拿到哪些信息。它们表面都叫“全局错误监听”,但覆盖范围和细节深度差异明显。
能捕获的错误类型不同
两者都能捕获 JS 运行时错误(如 ReferenceError、TypeError),但对资源加载类错误的处理能力有本质区别:
- window.onerror:只捕获脚本执行异常,完全无法感知图片、CSS、script 标签加载失败(例如 404 的 JS 文件或挂掉的 CDN 图片)
-
window.addEventListener('error'):既能捕获 JS 执行错误,也能捕获静态资源加载失败事件——只要错误发生在 HTML 元素上(
<img>、<script></script>、<link>等),就会触发该事件,且event.target就是那个出问题的 DOM 元素
触发时机与事件流阶段不同
同一个 JS 错误发生时,两个监听器的响应顺序和阶段不同:
-
window.addEventListener('error') 默认在冒泡阶段触发;若传入第三个参数
true(推荐),则在捕获阶段就介入,比window.onerror更早拿到错误 -
window.onerror 是独立于 DOM 事件流的机制,不参与捕获/冒泡,属于浏览器级错误钩子,触发时机略晚于捕获阶段的
addEventListener - 这意味着:如果你在捕获阶段用
addEventListener('error')做了event.preventDefault(),它不能阻止window.onerror再次执行(两者互不影响),但可以提前干预或标记某些错误
可获取的错误信息结构不同
参数设计直接反映监控粒度的粗细:
-
window.onerror 回调接收 5 个明确参数:
message、source、lineno、colno、error(Error 实例)。其中error.stack可取完整堆栈,信息结构化强、易解析 -
window.addEventListener('error') 回调只接收一个
Event对象。JS 执行错误时,event.error字段才存在(等价于window.onerror的第五个参数);而资源加载错误时,event.error为undefined,只能靠event.target和event.type判断类型,缺乏行号列号等上下文
对 Promise 拒绝错误均无能为力
这是容易被忽略的关键共性:
- 无论
window.onerror还是window.addEventListener('error'),都完全捕获不到未处理的 Promise rejection(即控制台显示Uncaught (in promise)的错误) - 这类错误必须单独监听:
window.addEventListener('unhandledrejection', handler),且其回调中通过event.reason获取原始错误对象 - 漏掉这个监听,线上 Promise 异常就会静默丢失,监控缺口明显











