Files
2026-07-16 16:34:18 +08:00

3.5 KiB
Raw Permalink Blame History

kind, name, category, scope, source_files
kind name category scope source_files
error_handling 后端统一响应与前端拦截器式错误处理 error_handling
**
backend/src/utils/response.js
backend/src/middleware/auth.js
backend/src/app.js
backend/src/config/redis.js
frontend/src/utils/request.js

1. 采用的体系与模式

  • 后端:Express + Sequelize无全局错误中间件。每个路由 handler 使用 try/catch 包裹业务逻辑,捕获异常后通过 logger.error 记录日志,再以统一的 ApiResponse.error() 返回 { code, msg, data } 结构。
  • 前端(frontend):基于 axios 的请求/响应拦截器集中处理 HTTP 状态码与业务码 code === 0 的错误,自动弹出 ElMessage、401 时清除本地 token 并跳转登录页。
  • 前端(frontend_v2):采用 alova + Naive UI 的独立实现,错误处理策略与 frontend 类似但组件库不同。
  • 未使用自定义 Error 类、未定义业务错误码枚举,也未使用 throw new CustomError(...) 这类结构化错误对象;错误信息以字符串形式在路由层直接构造。

2. 关键文件与位置

  • 后端统一响应封装:backend/src/utils/response.js
  • 认证中间件(401/403 错误入口):backend/src/middleware/auth.js
  • 应用启动与数据库同步异常兜底:backend/src/app.js
  • Redis 连接错误监听:backend/src/config/redis.js
  • 前端请求封装与拦截器:frontend/src/utils/request.js
  • 各业务路由(大量 try/catch + ApiResponse.error 示例):backend/src/routes/*.jsauth.js、blacklist.js、brands.js 等)

3. 架构与约定

  • 统一响应体:所有成功/失败接口均返回 { code: 1|0|2, msg, data }code=1 成功,code=0 业务错误,code=2 无数据。调用方可据此判断是否继续。
  • HTTP 状态码约定:认证失败返回 401,权限不足返回 403,其余业务错误默认 200 + code=0。未对 5xx 做全局兜底,依赖 Node 默认行为或路由内 catch。
  • 错误传播路径:路由层 → ApiResponse.error(msg) → 前端响应拦截器 → ElMessage.error(res.msg) 或直接 reject Promise,由业务组件自行处理。
  • 鉴权错误authMiddleware 区分 TokenExpiredError 与普通解析错误,分别返回“登录已过期”和“无效凭证”,前端据此提示并跳转。
  • 可跳过全局提示:前端支持在请求配置中设置 skipErrorToast: true,让上层组件自行控制错误提示(如推送进度弹窗场景)。

4. 开发者应遵循的规则

  • 新增路由一律用 try/catch 包裹核心逻辑,catch 中先 logger.error(e.message),再 res.json(ApiResponse.error('中文错误描述'))
  • 不要直接 throw 自定义错误对象到上层;当前代码库没有全局错误处理器来消费它。
  • 需要返回 HTTP 401/403 的场景(如鉴权、权限校验)优先使用 authMiddlewarerequireSuperAdmin,避免在各路由重复实现。
  • 前端发起请求时,如需自行展示错误(例如表单提交),可在 axios 配置中添加 skipErrorToast: true,并在 .catch 中手动 ElMessage.warning/error
  • 对于网络超时、DNS 解析失败等底层错误,前端拦截器会统一提示“网络错误”,业务层无需重复处理。
  • 若需引入更精细的错误分类(如参数校验失败 vs 数据库不可用),建议先在 utils/response.js 中扩展 ApiResponse 方法或在 validators/ 中集中抛出带 code 的错误对象,再由路由层统一转换,以保持前后端一致。