3.5 KiB
3.5 KiB
kind, name, category, scope, source_files
| kind | name | category | scope | source_files | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| error_handling | 后端统一响应与前端拦截器式错误处理 | error_handling |
|
|
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/*.js(auth.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 的场景(如鉴权、权限校验)优先使用
authMiddleware及requireSuperAdmin,避免在各路由重复实现。 - 前端发起请求时,如需自行展示错误(例如表单提交),可在 axios 配置中添加
skipErrorToast: true,并在.catch中手动ElMessage.warning/error。 - 对于网络超时、DNS 解析失败等底层错误,前端拦截器会统一提示“网络错误”,业务层无需重复处理。
- 若需引入更精细的错误分类(如参数校验失败 vs 数据库不可用),建议先在
utils/response.js中扩展ApiResponse方法或在validators/中集中抛出带 code 的错误对象,再由路由层统一转换,以保持前后端一致。