unhandledRejection事件用于捕获未catch的Promise拒绝,防止进程崩溃并发现遗漏错误处理;需在启动早期全局监听,记录日志而非直接退出,且不可替代主动错误处理。

Node.js 中的 unhandledRejection 事件用于捕获未被 catch 处理的 Promise 拒绝(reject)错误,防止进程意外崩溃,同时帮助开发者发现遗漏的错误处理逻辑。
为什么需要监听 unhandledRejection
Promise 被 reject 后若没有绑定 .catch() 或用 try/catch 包裹 await,该错误不会立即抛出,而是被推迟到当前事件循环结束。Node.js 会将其标记为“未处理的拒绝”,并在下一轮事件循环触发 unhandledRejection 事件。若不监听,Node.js 在未来版本中默认会终止进程(v15+ 已启用警告,v17+ 默认 fatal)。
如何正确监听 unhandledRejection
推荐在应用启动早期(如入口文件顶部)全局监听,确保覆盖所有异步路径:
- 使用
process.on('unhandledRejection', (reason, promise) => { ... }) -
reason是 Promise 拒绝时传入的值(可能是 Error 实例,也可能是字符串、数字等) -
promise是被拒绝的 Promise 对象,可用于调试(如打印堆栈或关联请求 ID) - 监听后建议记录日志,并根据业务决定是否
process.exit(1)(生产环境通常记录后继续运行,避免雪崩)
常见误区与注意事项
容易忽略的关键点:
立即学习“Java免费学习笔记(深入)”;
- 监听必须在 Promise 被创建前注册,否则可能错过事件(尤其动态 require 或延迟初始化模块时)
- 不能依赖
unhandledRejection替代主动错误处理——它只是兜底,不是最佳实践 - 同一个 Promise 只会触发一次该事件;若之后补上
.catch(),不会取消已发出的事件 - 若同步抛出错误(非 Promise reject),走的是
uncaughtException,与此事件无关
配合 rejectionHandled 做更精细控制
当 Promise 后来被处理(例如在 unhandledRejection 触发后才加 .catch()),Node.js 会发出 rejectionHandled 事件。可借此区分“真正遗漏”和“延迟处理”:
- 监听
rejectionHandled并维护一个待处理拒绝的 Map(以 promise 为 key) - 在
unhandledRejection中存入该 Map;在rejectionHandled中删除 - 定时清理长期滞留在 Map 中的 promise,作为潜在 bug 的线索










