多层嵌套 try...catch 无法捕获异步错误,关键在于每层职责明确;async/await 中 try 必须包裹 await 表达式;promise 链末尾须显式 .catch();禁止空 catch,需记录堆栈并明确处理策略;unhandledrejection 仅作兜底,不可依赖。

多层嵌套 try...catch 本身不解决异步错误捕获问题,反而容易制造“假兜底”——看起来包住了,其实错误根本没进 catch。关键不是加更多层,而是让每层明确知道:它该捕获什么、不该捕获什么、漏掉了谁。
async/await 的 try 必须包裹 await,不能只包函数调用
常见误写:
- 错:在非 async 函数里写 try { fetchUser() } —— fetchUser 返回 Promise,reject 不会触发 catch
- 错:在 async 函数里 try { fetchUser() } 却没 await —— Promise 被创建但未等待,拒绝后直接变成 unhandledrejection
- 对:async function load() { try { const user = await fetchUser(); ... } catch (e) { ... } }
Promise 链末尾必须显式 .catch(),不能依赖外层 try
即使你把整个 Promise 链放在 async 函数的 try 块里,只要链中某个 .then() 内部抛错且没接 .catch(),错误仍会逃逸:
- fetch('/api').then(res => res.json()).then(data => process(data)) —— 第二个 then 若 throw,外层 try 不管用
- 正确写法:fetch(...).then(...).then(...).catch(handleError)
- 更稳妥:统一用 await + try/catch,避免混用 .then/.catch 和 await
禁止空 catch,所有 catch 都要明确响应意图
一个空的 catch (e) {} 或只写 console.log('fail'),等于主动丢弃错误上下文:
- 至少记录 error.stack 和发生位置(比如加 traceId)
- 区分处理:是重试?降级?提示用户?还是必须上报并中断?
- 避免 catch 后 silent return 或 throw new Error('unknown') —— 损失原始堆栈和类型信息
用 unhandledrejection 兜底,但别只靠它“救火”
这个全局监听器是你最后一道防线,但它暴露的是设计漏洞:
- 监听时务必上报完整错误对象(包括 reason、promise、timestamp)
- 不要 event.preventDefault() 屏蔽警告——掩盖问题比报错更危险
- 上线后定期查 unhandledrejection 错误率,高发说明某类异步操作长期漏处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











