优化 async/await 异常响应的核心是让错误可识别、可区分、可应对,需按类型分层捕获(网络、http、业务)、注入上下文(action/url/timestamp)、区分用户提示(简洁无术语)与开发日志(含堆栈和脱敏参数),并确保每个 promise 显式处理。

优化 async/await 模式下的异常响应,核心不是让错误“不发生”,而是让错误“可识别、可区分、可应对”。重点在于分类处理、上下文注入和用户/开发分层提示。
按错误类型分层捕获与响应
同一 try/catch 里可能混着网络中断、HTTP 状态码异常(如 401/500)、JSON 解析失败、业务逻辑拒绝(如余额不足)。统一提示“操作失败”无法指导用户或开发者行动。
- 用 error.name 区分底层异常:如
TypeError(网络断开、fetch 失败)→ 提示“网络连接不稳定,请检查 Wi-Fi 或移动数据” - 用 response.status 判断 HTTP 层问题:401 → 清 token 并跳转登录;500/502 → “服务暂时不可用,稍后再试”
- 用 data.code 或 data.errorCode 处理业务层错误:如
code === 4001表示库存不足 → 提示“该商品已售罄”
注入关键上下文便于定位
仅靠 error.message 很难还原现场。原始错误信息要补全触发动作、请求路径、时间戳等脱敏后上下文。
- 在 catch 块中构造上下文对象:
{ action: 'submitOrder', url: '/api/order', timestamp: Date.now() } - 上报时一并传给监控系统(如 Sentry),支持按 action 或 url 聚合分析高频错误
- 避免直接打印
error.stack给用户,但开发日志中保留完整堆栈和 response headers(非敏感字段)
区分用户提示与开发日志
面向用户的文案必须简洁、无技术术语、带明确动作指引;开发侧日志则需保留原始 error 对象、请求参数(脱敏)、响应体片段。
- 用户侧:统一模板,如“提交订单失败,请检查网络后重试”——不暴露 URL、status、code
- 开发侧:在 catch 中调用
reportErrorToSentry(error, context),同时记录 console.error - 避免在 catch 里只写
console.log('出错了')或完全空着,也不要用throw 'string'(丢失 stack)
确保每个 Promise 都有兜底
未 await 或未 catch 的 Promise 会静默 rejected,既不报错也不提示,是线上故障的隐形源头。
- 所有关键异步调用必须被
await或.catch()显式处理 - 非关键请求(如埋点、统计)可用
.catch(() => {})忽略,但需加注释说明意图 - 启用 ESLint 规则
no-promise-reject-without-catch,从编码阶段拦截漏网之鱼










