统一兜底异常处理需将@exceptionhandler(exception.class)置于最末端,按从细到粗顺序排列处理器;响应禁用堆栈等敏感信息,仅返回500状态码、通用错误码及友好提示;日志须全量记录含上下文的error级别异常。

未知系统异常的统一兜底,核心是用 @ExceptionHandler(Exception.class) 做最后一道防线,不漏掉任何未被显式捕获的异常,同时保障安全、可追溯、响应可控。
必须放在异常处理链最末端
兜底方法不能写在前面,否则会“吃掉”本该由更具体处理器处理的异常。顺序要严格按从细到粗排列:
- MethodArgumentNotValidException(参数校验失败)
- NullPointerException、SQLException、IllegalArgumentException 等具体运行时异常
- 自定义业务异常(如 BusinessException)
- 最后才是 @ExceptionHandler(Exception.class)
响应内容要克制,不暴露细节
生产环境绝不能返回堆栈、类名、数据库语句或服务器路径。标准做法是:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- HTTP 状态码设为 500 Internal Server Error
- 响应体 code 字段统一用 500 或预设的系统错误码(如 9999)
- msg 字段只给用户看的友好提示,例如 “系统繁忙,请稍后再试”
- data 字段保持为 null,不塞任何服务端信息
日志记录必须完整且可定位
兜底方法里要主动记录原始异常全量信息,方便排查:
- 用 logger.error("系统未知异常", e) 打印带堆栈的 ERROR 日志
- 补充关键上下文:当前请求 URL、HTTP 方法、用户 ID(如有)、时间戳
- 避免只记 e.getMessage() —— 它通常为空或无意义
可选增强:区分环境行为
开发/测试环境可适度放宽,比如在响应中附带简单异常类型名(仅限非生产):
- dev 模式下 msg 可写成 “系统异常:{}”,format(e.getClass().getSimpleName())
- prod 模式下严格返回通用文案,不加任何动态内容
- 通过 spring.profiles.active 判断环境,避免硬编码










