async封装统一异常处理的核心是抽离错误捕获逻辑,使业务代码专注成功路径,通过高阶函数safeRun接收异步函数、结构化返回结果、分层定制错误响应、保留原始错误信息,并与框架异常机制协同分工。

用 async 封装统一异常处理接口,核心是把错误捕获逻辑从每个业务调用中抽离出来,让业务代码只关注“成功路径”,同时保留对错误类型、上下文和响应行为的精细控制。关键不在消灭 try/catch,而在让它只出现一次、定义清晰、可复用。
封装一个可复用的 async 执行器
定义一个高阶函数(如 safeRun 或 apiRequest),它接收一个异步函数(不是已执行的 Promise),内部用 try/catch 包裹执行,并统一处理结果与错误:
- 传入函数而非 Promise,避免调用即执行导致无法拦截
- 支持同步函数和
async函数,内部自动适配(如用await Promise.resolve(fn())) - 返回结构化元组或对象,例如
[data, error]或{ success, data, error },便于解构判断 - 允许透传配置项:是否打印日志、是否弹 Toast、是否携带请求名、是否自动重试等
分层定制错误响应逻辑
不同场景需要不同错误反馈方式,可在封装层按职责分层定制:
-
API 层:检查 HTTP 状态码 + 业务 code 字段(如
res.status === 200 && data.code === 0),不满足则主动throw统一错误 - UI 层:对接 toast、loading 状态、错误占位图;失败时触发提示,成功时关闭 loading 并更新视图
- 工具层:自动上报错误(含 traceId、时间戳、堆栈)、写入本地日志、触发监控告警
保留原始错误信息,避免“黑盒化”
统一处理不等于模糊错误来源。需确保:
- 错误对象不被吞掉或简单转成字符串,保留
name、message、stack和自定义字段(如code、requestId) - 业务异常应继承标准 Error,并携带结构化字段(如
new ApiError(401, '登录过期')) - 不强制静默失败——调用方仍可选择
if (error) { ... }或继续throw error向上冒泡
与框架机制协同,不越界兜底
明确封装边界,避免误以为“一包治百病”:
- Express/FastAPI 中,该封装适用于路由 handler 内部,但全局异常仍需配合
app.use((err, req, res, next) => {...})或@app.exception_handler - Spring Boot 中,它适合 service 层调用,而控制器层异常仍由
@ControllerAdvice拦截,二者分工互补 - 不处理 Filter、Interceptor、@Async、定时任务中的异常——这些需各自独立兜底

















