跳到主要内容

异常处理与恢复

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件面向 yudao-cloud 的异常处理与恢复体系,系统性阐述全局异常处理器的实现机制、异常分类与处理策略、认证与授权失败的响应流程、错误码设计规范与国际化支持思路、以及异常监控与日志记录的最佳实践。目标是帮助开发者快速理解并高效扩展异常处理能力,提升系统的可观测性与可维护性。

项目结构

围绕异常处理的关键模块与文件分布如下:

  • 全局异常处理:GlobalExceptionHandler(Rest + 异常兜底)、GlobalResponseBodyHandler(响应包装与访问日志辅助)
  • 错误码与返回体:GlobalErrorCodeConstants、ErrorCode、CommonResult、ServiceException
  • 业务模块错误码:各模块的 ErrorCodeConstants(如系统、基础设施)
  • 网关认证过滤:TokenAuthenticationFilter(Token 校验与登录态判定)
  • 异常监控落地:API 错误日志表(infra_api_error_log)

Mermaid Diagram Code:

graph TB
subgraph "Web 层"
GEX["GlobalExceptionHandler<br/>全局异常处理器"]
GRBH["GlobalResponseBodyHandler<br/>响应包装与日志辅助"]
end
subgraph "通用异常与返回"
GEC["GlobalErrorCodeConstants<br/>全局错误码"]
EC["ErrorCode<br/>错误码对象"]
SR["CommonResult<br/>统一返回体"]
SE["ServiceException<br/>业务异常"]
end
subgraph "模块错误码"
SYS["系统模块错误码"]
INFRA["基础设施模块错误码"]
end
subgraph "网关与认证"
TAF["TokenAuthenticationFilter<br/>Token 校验"]
end
subgraph "异常监控"
DB["API 错误日志表<br/>infra_api_error_log"]
end
GEX --> SR
GEX --> GEC
GEX --> EC
GEX --> SE
GRBH --> SR
TAF --> GEX
GEX --> DB
SYS --> EC
INFRA --> EC

图表来源

章节来源

核心组件

  • 全局异常处理器(@RestControllerAdvice)
    • 负责将各类异常翻译为统一的 CommonResult 响应,包含错误码与错误信息。
    • 提供参数校验、请求方法不匹配、资源不存在、权限不足、业务异常、系统异常等分类处理。
    • 提供兜底异常处理与异步写入 API 错误日志的能力。
  • 全局响应包装处理器(@ControllerAdvice)
    • 不改变控制器返回结构的前提下,记录返回结果,用于访问日志采集。
  • 错误码与返回体
    • GlobalErrorCodeConstants:HTTP 语义化的全局错误码(400/401/403/404/405/500 等)。
    • ErrorCode:错误码对象,承载 code 与 msg。
    • CommonResult:统一返回体,封装 code、msg、data。
    • ServiceException:业务异常,携带业务错误码与消息。
  • 模块错误码
    • 各模块在各自 API 模块下定义业务错误码,遵循“模块段”命名空间,便于定位与扩展。
  • 网关认证过滤
    • TokenAuthenticationFilter:对请求进行 Token 校验,结合系统侧校验结果处理登录态与权限问题。
  • 异常监控
    • GlobalExceptionHandler 内部异步写入 API 错误日志,落库到 infra_api_error_log,包含堆栈、用户信息、请求上下文等。

章节来源

架构总览

全局异常处理与恢复的整体流程如下:

Mermaid Diagram Code:

sequenceDiagram
participant C as "客户端"
participant GW as "网关/路由"
participant CTRL as "控制器"
participant EX as "全局异常处理器"
participant LOG as "API 错误日志"
C->>GW : "HTTP 请求"
GW->>CTRL : "转发请求"
CTRL-->>CTRL : "执行业务逻辑"
alt "发生异常"
CTRL-->>EX : "抛出异常"
EX->>LOG : "异步写入异常日志"
EX-->>C : "返回统一错误响应"
else "正常返回"
CTRL-->>GW : "返回业务结果"
GW-->>C : "返回统一响应"
end

图表来源

详细组件分析

全局异常处理器(@RestControllerAdvice)

  • 职责
    • 分类捕获并处理参数缺失、类型不匹配、校验失败、请求方法不支持、资源不存在、权限不足、业务异常、系统异常等。
    • 对业务异常进行格式化输出;对系统异常进行兜底处理并记录异常日志。
    • 对特定数据库异常(如表不存在)进行模块化提示。
  • 关键处理策略
    • 参数类异常:统一返回 400(请求参数不正确)。
    • 权限不足:返回 403(没有该操作权限)。
    • 业务异常:透出业务错误码与消息。
    • 系统异常:返回 500(系统异常),并异步写入 API 错误日志。
    • 特定异常:如表不存在,按模块提示“功能未实现/未开启”。

Mermaid Diagram Code:

flowchart TD
Start(["进入异常处理"]) --> Type{"异常类型?"}
Type --> |参数缺失/类型不匹配/校验失败| BadReq["返回 400 错误"]
Type --> |请求方法不支持/资源不存在| NotFound["返回 404/405 错误"]
Type --> |权限不足| Forbidden["返回 403 错误"]
Type --> |业务异常| BizErr["透出业务错误码与消息"]
Type --> |系统异常| SysErr["返回 500 并记录异常日志"]
Type --> |表不存在| ModHint["按模块提示未导入/未启用"]
BadReq --> End(["结束"])
NotFound --> End
Forbidden --> End
BizErr --> End
SysErr --> End
ModHint --> End

图表来源

章节来源

全局响应包装处理器(@ControllerAdvice)

  • 职责
    • 不改变控制器返回结构的前提下,记录返回结果,用于访问日志采集。
    • 与全局异常处理器配合,保证日志与返回体的一致性。

章节来源

错误码设计与国际化支持

  • 全局错误码(0-999)
    • 采用 HTTP 语义化错误码,覆盖客户端错误(400/401/403/404/405/429/423/499)、服务端错误(500/501/502)与自定义错误(900/901/999)。
  • 业务错误码(≥10^9)
    • 各模块在各自 API 模块下定义,采用“模块段”命名空间,便于扩展与维护。
  • 国际化支持
    • 错误码对象设计预留国际化准备(注释明确),可通过消息源与参数化占位符实现多语言提示。

章节来源

认证与授权失败处理流程

  • 网关层 Token 校验
    • TokenAuthenticationFilter 调用系统侧 Token 校验接口,根据返回结果判断登录态与权限。
    • 当系统返回 401(UNAUTHORIZED)时,视为 Token 过期或无效,返回空用户以触发后续登录态失效处理。
  • 控制器层权限校验
    • 使用 Spring Security 的权限注解(如 @PreAuthorize)时,AOP 拦截抛出 AccessDeniedException,由全局异常处理器统一转为 403 响应。
  • 刷新令牌与过期处理
    • 刷新令牌过期场景返回业务错误码(如 401),前端据此引导重新登录或提示刷新失败。

Mermaid Diagram Code:

sequenceDiagram
participant C as "客户端"
participant GW as "网关"
participant F as "TokenAuthenticationFilter"
participant S as "系统侧校验"
participant CTRL as "控制器"
participant SEC as "权限校验"
C->>GW : "携带 Token 请求"
GW->>F : "进入过滤链"
F->>S : "校验 Token"
alt "返回 401"
S-->>F : "UNAUTHORIZED"
F-->>C : "LOGIN_USER_EMPTY登录态失效"
else "返回有效用户"
S-->>F : "用户信息"
F-->>CTRL : "放行"
CTRL->>SEC : "权限校验"
alt "权限不足"
SEC-->>CTRL : "AccessDeniedException"
CTRL-->>GW : "抛出异常"
GW-->>C : "返回 403"
else "权限通过"
CTRL-->>C : "业务响应"
end
end

图表来源

章节来源

异常监控与日志记录最佳实践

  • 异步写入 API 错误日志
    • 全局异常处理器在系统异常时异步写入 API 错误日志,包含异常堆栈、用户信息、请求上下文、TraceId 等关键信息。
  • 数据库表结构
    • infra_api_error_log 包含异常名、消息、根因、栈轨迹、类/方法/行号、处理状态等字段,便于检索与分析。
  • 生产环境策略
    • 仅在 /admin-api 或非生产环境记录异常日志,避免生产环境日志风暴。

Mermaid Diagram Code:

flowchart TD
EStart(["捕获系统异常"]) --> Build["组装异常日志对象"]
Build --> Async["异步写入 API 错误日志"]
Async --> Resp["返回 500 统一错误"]
Resp --> EEnd(["结束"])

图表来源

章节来源

依赖关系分析

  • 组件耦合
    • GlobalExceptionHandler 依赖 CommonResult、GlobalErrorCodeConstants、ErrorCode、ServiceException、ApiErrorLogApi 等。
    • TokenAuthenticationFilter 依赖系统侧 OAuth2TokenApi,用于 Token 校验与登录态判定。
    • 各模块错误码通过 ErrorCodeConstants 与通用错误码解耦。
  • 外部依赖
    • API 错误日志持久化依赖 infra_api_error_log 表结构。

Mermaid Diagram Code:

graph LR
GEX["GlobalExceptionHandler"] --> SR["CommonResult"]
GEX --> GEC["GlobalErrorCodeConstants"]
GEX --> EC["ErrorCode"]
GEX --> SE["ServiceException"]
GEX --> LOG["ApiErrorLogApi"]
TAF["TokenAuthenticationFilter"] --> SYS["OAuth2TokenApi"]
SYS --> GEX
MOD_SYS["系统模块错误码"] --> EC
MOD_INFRA["基础设施模块错误码"] --> EC

图表来源

章节来源

性能考量

  • 异常日志异步化:避免阻塞主线程,降低异常路径对吞吐的影响。
  • 条件记录:仅在特定路径或非生产环境记录异常日志,减少 IO 压力。
  • 忽略噪声:对已知忽略的错误消息(如“无效的刷新令牌”)不打印冗余日志,降低控制台噪音。
  • 响应体最小化:统一返回体仅包含必要字段,减少序列化开销。

故障排查指南

  • 常见问题定位
    • 400/401/403/404/405:检查请求参数、认证与授权配置。
    • 500:查看 API 错误日志表,定位异常堆栈与请求上下文。
    • 表不存在:根据模块提示确认对应模块是否启用与表结构是否导入。
  • 关键排查步骤
    • 根据 TraceId 在链路追踪系统中检索请求链路。
    • 在 API 错误日志表中查询异常记录,核对异常名、根因、栈轨迹与处理状态。
    • 结合 TokenAuthenticationFilter 的返回值判断登录态与权限问题。

章节来源

结论

yudao-cloud 的异常处理与恢复体系通过全局异常处理器与统一返回体,实现了对各类异常的标准化处理与可观测性保障。配合模块化错误码与网关认证过滤,能够清晰地区分认证、授权与业务异常,并通过 API 错误日志实现高效的故障定位与恢复。建议在扩展新模块时严格遵循错误码命名规范与国际化预留设计,持续优化异常日志策略与性能表现。

附录

  • 错误码设计规范
    • 全局错误码:0-999,遵循 HTTP 语义。
    • 业务错误码:≥10^9,按模块段划分,避免冲突。
    • 国际化:预留消息参数化与多语言支持。
  • 国际化支持方案
    • 使用错误码对象承载消息模板与参数,结合消息源实现多语言渲染。
    • 对用户可见的错误提示优先采用参数化模板,便于本地化维护。
用户文档
AI 助手
Agent 列表
请选择一个 Agent 开始对话
AI 问答