You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

3.2 KiB

kind name category scope source_files
error_handling 统一异常处理与错误码体系 error_handling [**] [crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java crm-base/src/main/java/com/crm/base/domain/result/Result.java crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java]

该 CRM 单体工程采用 Spring Boot + MyBatis-Plus 架构,在 crm-base 公共模块中构建了完整的错误处理体系,核心由统一响应体、错误码枚举、业务异常类与全局异常处理器组成。

1. 统一响应体与错误码

  • Result<T>:所有 Controller 返回值必须包装为 Result,HTTP 状态码除框架级错误外一律返回 200,业务成败通过 code/success 字段判断。
  • ResultCodeEnum:定义分段规范——0 成功;400xx 请求参数错误;401xx 认证错误;403xx 权限错误;404xx 资源不存在;405xx 请求方式错误;500xx 系统/外部调用错误;6xxxx 业务错误(60001 通用,各模块从 61000 起按区间划分)。

2. 业务异常类型

  • BusinessErrorException:业务代码主动抛出的通用业务异常,支持传入 message、ResultCodeEnum 或自定义 code+msg。
  • MissingParameterException:缺少必填参数时抛出。
  • PermissionErrorException:权限校验失败时抛出。
  • ResourceNotExistException:资源不存在时抛出。

3. 全局异常处理器

  • GlobalExceptionHandlerAdvice:使用 @RestControllerAdvice 集中处理所有异常。约定业务/校验类异常 HTTP 状态码返回 200,通过 Result.code 区分;未预期的系统异常返回 500 并记录完整堆栈以便通过 traceId 排查。
  • 覆盖的异常类型包括:@Valid/@Validated 参数校验(MethodArgumentNotValidException、BindException、ConstraintViolationException)、请求体解析错误(HttpMessageNotReadableException)、参数类型不匹配(MethodArgumentTypeMismatchException)、Spring Security 授权拒绝(AccessDeniedException)、静态资源不存在(NoResourceFoundException)、上传文件超限(MaxUploadSizeExceededException)、Content-Type 不支持等。

4. Spring Security 层异常处理

  • SecurityExceptionHandlers:实现 AuthenticationEntryPoint 和 AccessDeniedHandler,处理进不了 Controller 的认证/授权异常。未登录/登录过期返回 401 + 40103;已登录但无权限返回 403 + 40301。

5. 断言工具辅助

  • AssertUtils:配合 BusinessErrorException 使用,在业务代码中进行参数校验和条件断言。

架构设计要点

  • 分层处理:Security 过滤器链层处理认证/授权异常,Controller 层通过全局异常处理器处理业务/参数异常,兜底捕获 Exception 处理未知系统异常。
  • 统一出口:所有错误最终都通过 Result.fail() 返回标准 JSON 结构,前端只需检查 code/success 字段。
  • 可追溯性:系统异常记录完整堆栈日志,结合 TraceIdFilter 实现的 traceId 便于问题定位。