unhandledrejection 是浏览器全局事件,用于捕获未处理的 promise 拒绝,需在全局尽早监听以记录错误日志;事件对象含 reason 和 promise 属性,可提取信息并上报,但不可替代主动错误处理。

在 JavaScript 中,unhandledrejection 是一个全局事件,用于捕获未被 .catch() 或 await 处理的 Promise 拒绝(reject)。它非常适合用来统一记录前端 Promise 错误日志,防止异常静默丢失。
监听 unhandledrejection 事件
在页面加载早期(如 <script></script> 标签内或模块入口)注册监听器即可:
注意:必须在全局作用域(如 window)上监听,且建议尽早注册,避免漏掉早期的 rejected Promise。
- 事件对象是
PromiseRejectionEvent,包含reason(拒绝原因,可能是 Error 实例、字符串、任意值)和promise(被拒绝的 Promise 实例) - 即使
reason不是 Error 对象,也应尽量提取可用信息(如toString())用于日志 - 调用
event.preventDefault()可阻止浏览器默认的控制台警告(但不推荐屏蔽,除非你有完整替代方案)
基础日志记录示例
以下是一个简洁实用的监听写法:
window.addEventListener('unhandledrejection', event => {
const reason = event.reason;
const message = reason instanceof Error
? `${reason.name}: ${reason.message}`
: String(reason);
console.error('[Unhandled Rejection]', message, {
stack: reason instanceof Error ? reason.stack : null,
url: window.location.href,
timestamp: new Date().toISOString()
});
// ✅ 这里可发送到日志服务,例如:
// reportToSentry({ type: 'unhandledrejection', message, stack: reason?.stack });
});
常见陷阱与建议
-
不要只依赖 unhandledrejection 做错误处理:它只是兜底机制。业务中仍需主动
.catch()或try/catch,确保逻辑健壮 - 避免重复上报:如果已用 Sentry、Bugsnag 等 SDK,它们通常自动集成该事件,手动监听可能导致重复日志
-
注意跨 iframe 场景:
unhandledrejection不会跨 iframe 冒泡,需在每个 iframe 的上下文中单独监听 -
Node.js 不支持:该事件仅存在于浏览器环境;Node.js 使用
process.on('unhandledRejection')
配合 Promise 链做更精准定位
有时 reason 缺少上下文(比如后端返回的错误码),可在关键 Promise 创建时打标记:
fetch('/api/data')
.then(res => res.json())
.catch(err => {
// 主动添加上下文,便于后续追踪
err.context = { api: '/api/data', method: 'GET' };
throw err;
});
这样在 unhandledrejection 中就能读取 event.reason.context,提升日志可排查性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











