关键在于分层设防,同步错误用 try-catch,异步错误须在 Promise 链末尾 .catch() 或 async/await 中处理;杜绝悬空 Promise;全局监听 unhandledrejection 和 error 事件并结构化上报。

关键在于分层设防,不依赖单一机制。异步错误容易“漏网”,不是因为没写 try-catch,而是没覆盖调用链末端和事件循环边缘场景。
同步与异步错误要分开对待
同步代码出错会立即中断执行栈,try-catch 有效;但异步操作(如 fetch、setTimeout、Promise 构造器内抛错)发生在任务队列中,外层 try-catch 捕不到。
- 不要对异步回调函数本身加
try-catch,而要在 Promise 链末尾加.catch(),或在async函数内用await+try-catch - 避免在
Promise构造器里直接throw,应统一走reject();否则错误会变成未捕获的异常,而非未处理的 rejection - 像
setTimeout(() => { throw new Error('x') }, 0)这类代码,必须靠window.onerror或process.on('uncaughtException')捕获,try-catch完全无效
确保每个 Promise 都有明确归宿
“悬空 Promise”是线上 UnhandledRejection 的主因——函数返回了 Promise,但调用方没 await 也没 .catch()。
- 所有顶层异步调用(如页面初始化、按钮点击 handler)必须显式处理:用
.catch()兜底,或await后包裹在try-catch中 - Node.js 路由中常用
asyncHandler包装中间件,自动将 Promise 错误转给next(),避免遗漏 - 禁止只写
someAsyncFn();这种无处理的调用;哪怕只是日志,也应补上.catch(console.error)
全局兜底不能省,但不能当主力
它不解决具体问题,但能防止崩溃、收集线索、触发告警。
- 浏览器端监听
unhandledrejection:捕获所有未.catch()的 Promise 拒绝,包括fetch失败、JSON.parse异常等 - 同时监听
error事件(window.onerror),覆盖脚本加载失败、语法错误、同步运行时异常 - 上报时至少带上
error.message、error.stack、当前 URL 和时间戳;避免只打印"Something went wrong"
结构化错误,让恢复更可控
静默吞掉错误或只打日志,等于放弃恢复机会。错误对象要有区分度,才能做针对性处理。
- 自定义错误类,继承
Error,添加code(如'NETWORK_TIMEOUT')、status(HTTP 状态码)、retryable: true等字段 - 网络类错误可自动重试;表单校验错误直接提示用户;权限错误跳转登录页——这些逻辑都依赖错误类型判断
- 不要在
catch里return null或空对象了事,除非业务明确允许“降级”,否则应重新抛出或转为更清晰的错误
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











