unhandledrejection 是标准事件机制,用于兜底未处理的 Promise 拒绝;浏览器用 window.addEventListener('unhandledrejection'),Node.js 用 process.on('unhandledRejection');能捕获 async 抛错或 Promise.reject() 未 catch 的情况,不能捕获同步错误或已处理 Promise。
直接在应用启动时注册 unhandledrejection 监听器,就能捕获那些没被 try/catch 或 .catch() 拦住的 async 函数内部错误。它不是“网关”,而是一个标准的浏览器/Node.js 事件机制,专为兜底漏掉的 Promise 拒绝设计。
这是最常用也最稳妥的方式,必须尽早执行(比如在 <head> 中或入口 JS 第一行):
'unhandledrejection'
event.reason(拒绝值,通常是 Error 实例)和 event.promise(出问题的 Promise)event.preventDefault() 可抑制浏览器控制台的黄色警告,但不影响其他监听器运行v15+ 版本中未监听会直接崩溃,所以必须显式处理:
process.on('unhandledRejection', (reason, promise) => { ... })
'rejectionHandled',用于发现“延迟补 catch”的情况明确边界才能避免误用:
async 函数里 throw new Error() 但没被外层 try/catch 包裹的情况;Promise.reject() 后没接 .catch() 或 await 的场景window.onerror)、已处理的 Promise(哪怕晚几毫秒加 .catch() 就不算“未处理”)、跨域脚本错误、资源加载失败、框架内部封装过的错误(如 Vue 渲染异常)reason 不一定带完整堆栈,尤其当 reject 值是字符串或普通对象时,所以优先在 async 内部做 try/catch
真正健壮的做法是分层防御:
await 都配 try/catch,按错误类型做不同响应(重试、降级、提示)unhandledrejection 并关联用户行为throw 或 reject 新 Promise