在 async 函数中写容错代码的核心是主动捕获异常、合理控制流程、避免未处理的 promise 拒绝,并确保关键逻辑不因局部失败而中断整体执行;需用 try/catch 精准包裹每个 await 表达式,区分错误类型并采用重试、降级、超时等可组合策略。

在 async 函数中写容错代码,核心是主动捕获异常、合理控制流程、避免未处理的 Promise 拒绝,并确保关键逻辑不因局部失败而中断整体执行。
用 try/catch 包裹 await 表达式
async 函数内部的 await 一旦抛出错误,会像同步代码一样触发异常,因此最直接的方式就是用 try/catch 捕获。注意:只对真正需要容错的 await 调用加 try/catch,避免过度包裹影响可读性。
- 每个可能失败的异步操作(如 API 请求、数据库查询)都应单独 try/catch,便于定位问题和差异化处理
- 不要把整个 async 函数体包在一个大 try/catch 里——掩盖了错误来源,也容易让本该终止的流程继续执行
- catch 中可以重试、降级、记录日志或返回默认值,而不是简单 throw 或忽略
避免未处理的 Promise 拒绝
当 await 后面的 Promise 被拒绝且没有被 catch 捕获时,Node.js 会触发 unhandledrejection 事件,严重时导致进程退出。常见陷阱包括:
- 忘记 await 就直接调用 async 函数(返回 Promise 但没处理)
- 在数组方法(如 map、forEach)中使用 await 却未等待结果
- 定时器或事件回调中启动的 async 操作未做错误兜底
推荐做法:对所有启动的 Promise 显式处理拒绝,例如用 .catch(() => {}) 或包装成安全调用工具函数。
设计可组合的错误处理策略
不同场景需要不同容错行为,比如网络请求适合重试 + 退避,用户输入校验失败适合提前返回,数据库写入失败可能需回滚。可封装成可复用的高阶函数:
- retryAsync(fn, options):自动重试指定次数,支持指数退避
- fallbackAsync(primary, fallback):primary 失败时执行 fallback,常用于服务降级
- timeoutAsync(promise, ms):为 Promise 添加超时控制,防止长期挂起
这些工具让业务逻辑更专注核心路径,错误策略解耦且可测试。
区分错误类型,做精准响应
不是所有错误都该同等对待。HTTP 请求失败可能是 404(资源不存在)、503(服务不可用)或网络超时,处理方式应不同:
- 用自定义错误类(如 NetworkError、ValidationError、AuthError)分类抛出
- 在 catch 中 instanceof 判断类型,再决定是重试、提示用户、跳过还是告警
- 避免只靠 error.message 字符串匹配——脆弱且难维护
这样能让容错逻辑随业务演进而保持清晰和可控。











