unhandledrejection 是用于捕获未处理 promise 拒绝的全局事件,浏览器中通过 window.addeventlistener('unhandledrejection') 监听,node.js(v15+)中通过 process.on('unhandledrejection') 监听,需尽早注册,接收 reason 和 promise 参数,不可捕获同步错误。

unhandledrejection 是 JavaScript 中用于捕获 Promise 被 reject 但未被 .catch() 或 await 处理的全局事件。它**只在浏览器和 Node.js(v15+)中可用**,作用是防止“静默失败”,便于调试和错误上报。
浏览器中监听 unhandledrejection
直接在全局 window 对象上监听该事件即可:
示例:
window.addEventListener('unhandledrejection', (event) => {
console.error('未处理的 Promise 拒绝:', event.reason);
// 可选:阻止默认行为(如控制台警告)
event.preventDefault();
});
注意:
- event.reason 是 Promise 的 reject 值(可能是 Error 实例、字符串、数字等);
- 调用 event.preventDefault() 可抑制浏览器默认的控制台警告(但不推荐屏蔽,除非你有完整日志方案);
- 此监听需尽早注册(如脚本最顶部),避免漏掉早期 Promise 错误。
Node.js 中监听 unhandledRejection
Node.js 使用 process 对象监听,事件名是 全小写:unhandledRejection(注意大小写):
示例:
process.on('unhandledRejection', (reason, promise) => {
console.error('未处理的 Promise 拒绝:', reason);
console.error('关联 Promise:', promise);
<p>// 建议:记录日志后主动退出(避免进程继续运行在异常状态)
// process.exit(1);
});
</p>
关键点:
- 回调接收两个参数:reason(reject 值)和 promise(被拒绝的 Promise 实例);
- Node.js 默认会在未监听该事件时打印警告,并在后续版本中可能触发进程退出(v15+ 默认行为已变更);
- 生产环境建议记录错误并考虑 process.exit(1),或结合 process.on('beforeExit') 做清理(但需谨慎,避免掩盖真正问题)。
注意事项与常见误区
- 该事件不能捕获同步错误(如
throw new Error()),同步异常需用window.onerror(浏览器)或process.on('uncaughtException')(Node.js); - Promise 链中只要任意一环有
.catch()或顶层try/catch(配合await),就不会触发此事件; - 重复监听不会覆盖,多个监听器会依次执行;
- 在模块作用域中监听是安全的(如 ES 模块顶部),无需挂载到 globalThis;
- 某些打包工具(如 Webpack)或测试框架(如 Jest)可能拦截或模拟 Promise 行为,导致事件不触发——可临时加
console.log(Promise)确认是否为原生 Promise。
补充:如何主动触发测试
快速验证监听是否生效:
浏览器或 Node.js 中运行:
setTimeout(() => {
Promise.reject(new Error('测试未处理的拒绝'));
}, 0);
或更直接:
Promise.reject('oops');
确保没有 .catch() 或 await 捕获,就能触发监听器。











