全局异常处理器应分层处理异常类型:业务异常返回400+提示,参数校验异常提取字段错误,404统一友好文案,数据库/第三方异常仅对外返回“服务暂时不可用”,兜底exception必须记录完整堆栈;封装buildresponse统一构建响应;使用errorenum管理错误码;日志、监控、告警等横切逻辑需分离。

全局异常处理器的代码结构优化,核心是让逻辑清晰、职责分明、可维护性强。不是堆砌方法,而是有层次地组织处理流程。
按异常类型分层处理,避免一个兜底方法包打天下
把不同性质的异常分开响应,既利于排查,也方便前端区分处理:
- 业务异常(如
BusinessException)返回 400 状态码 + 明确提示,不暴露技术细节 - 参数校验异常(
MethodArgumentNotValidException)提取字段级错误信息,比如“手机号格式不正确” - 资源未找到(
NoHandlerFoundException或ResponseStatusException)统一返回 404 + 友好文案 - 数据库/第三方服务异常(如
DataAccessException、FeignException)记录完整堆栈,但对外只返回“服务暂时不可用” - 兜底的
Exception只做最后保障,必须记录完整异常对象(logger.error("系统异常", e)),不能只记e.getMessage()
抽离通用响应构建逻辑,避免重复编码
每个@ExceptionHandler方法里都手动 new Result 或拼 JSON,容易出错且难统一。建议封装一个构建方法:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 定义
buildResponse(ErrorEnum error, Throwable e, Map<string object> context)</string>方法,集中处理状态码、日志上下文、traceId 注入等 - 让各 handler 方法只负责判断类型和提取关键信息,响应组装交给统一入口
- 例如参数校验异常只需提取第一个错误字段信息,其余交由
buildResponse补全时间戳、traceId、监控指标等
引入异常分类枚举与错误码体系
不用硬编码数字状态码或字符串消息,改用枚举管理错误定义:
- 定义
ErrorEnum,包含code、message、httpStatus、logLevel等字段 - 业务抛出异常时直接关联枚举项:
throw new BusinessException(ErrorEnum.USER_NOT_FOUND) - 全局处理器中通过
e.getErrorEnum()快速获取配置,减少 if-else 和字符串匹配
分离日志、监控、告警等横切关注点
异常处理不只是返回 JSON,还承担可观测性职责。但这些不该混在响应构造里:
- 日志记录统一走 MDC + traceId,确保每条日志带链路标识
- 监控指标(如 Prometheus counter)在 handler 内按错误类型打点,不侵入业务逻辑
- 严重异常(如数据库连接池耗尽)可触发异步告警,但主流程不阻塞
- 避免在 handler 中做耗时操作(如远程调用、文件写入),保持响应轻量










