全局错误拦截需监听 unhandledrejection 事件捕获未处理的 promise 拒绝,浏览器用 window.addeventlistener,node.js 用 process.on;搭配 window.onerror 补充同步错误;须早期注册,且不能替代 try/catch 等局部处理。

为 async 函数设置全局错误拦截,本质是捕获那些“漏掉”的 Promise 拒绝(即未被 try/catch、.catch() 或 await 后续处理的 rejection)。这不能靠监听函数本身实现,而是通过浏览器或 Node.js 提供的标准全局事件机制。
监听 unhandledrejection 事件
这是最直接、最标准的方式,专门用于捕获未处理的 async/await 错误(底层就是 Promise reject)。
- 浏览器中使用
window.addEventListener('unhandledrejection', handler) - Node.js(v15+)中使用
process.on('unhandledRejection', (reason, promise) => { ... }) - 事件对象含
reason(拒绝原因,可能是 Error 或任意值)和promise(出问题的 Promise 实例) - 建议在脚本加载早期注册,避免错过初始化阶段的异常
搭配 window.onerror 做全链路兜底
window.onerror 负责捕获同步错误、资源加载失败、以及部分异步脚本错误(如 setTimeout 中抛出的异常),但它不捕获 Promise reject。因此它和 unhandledrejection 是互补关系,不是替代关系。
- 注册方式:
window.onerror = (msg, url, line, col, error) => { ... } - 返回
true可阻止浏览器默认错误提示(如控制台红字) - 注意:它无法拿到 Promise 异常的完整上下文,仅作辅助补充
Node.js 环境需额外注意 rejectionHandled
在 Node.js 中,若一个 Promise 最初被拒绝但后续又被 .catch() 处理,会触发 rejectionHandled 事件。配合 unhandledRejection 可识别“延迟捕获”行为,便于调试潜在隐患。
process.on('unhandledRejection', (reason, promise) => { /* 初次拒绝 */ })process.on('rejectionHandled', (promise) => { /* 后来被 catch 了 */ })- v15+ 默认未监听
unhandledRejection会导致进程退出,必须显式处理
这不是万能兜底,关键还在代码层
全局监听只是最后一道防线,不能替代良好的局部错误处理习惯:
- async 函数内部优先用
try/catch显式包裹await表达式 - 避免
fetch().then(...)这类写法——HTTP 状态码 404/500 不会 reject,需手动检查res.ok - 并发请求慎用
Promise.all:一个失败就全失败;改用Promise.allSettled可分别获取结果,但它不会触发unhandledrejection -
unhandledrejection不捕获已处理的 Promise 错误,也不适用于Promise.allSettled场景











