统一错误码机制需用枚举实现类型安全、语义化编码(如b1001)、绑定异常实例、解耦提示语与code、保留第三方原始错误详情。

设计统一的错误码机制,关键是让错误码可识别、可管理、可演进,而不是只图一时写得快。
用枚举定义错误码,别用字符串或常量
错误码必须是类型安全、IDE可提示、编译期可校验的。枚举天然满足这些要求,还能自带消息和状态码:
- 每个枚举项代表一个明确失败场景,比如 USER_NOT_FOUND、ORDER_EXPIRED
- 字段至少包含:code(字符串或整数)、message(带占位符,如"用户 {0} 不存在")、httpStatus(如 HttpStatus.NOT_FOUND)
- 避免纯数字码(如1001),优先用语义化字符串;若需数字,建议模块前缀+序号(如 USER_001)
- 枚举构造器里不调用外部服务或读配置——类加载阶段出错会导致应用启动失败
错误码要绑定到异常实例上,不是“查表式”使用
抛出异常时,错误码信息必须固化在异常对象里,不能靠处理器临时去枚举里查。
- 自定义异常(如 BusinessException)构造时传入枚举,并把 code、message(填充后)、httpStatus 全部存为 final 字段
- 提供 getErrorCode()、getHttpStatus() 等方法,全局处理器直接取用,不反射、不 instanceof 分发
- 禁止在 @ExceptionHandler 里再根据异常类型 switch 枚举——这破坏封装,也违反开闭原则
错误码结构要兼顾人读和机器判
五位或六位编码比单个字符串更利于监控与聚合,但不能过度设计。
- 推荐格式:来源字母 + 四位编号,例如 B1001(B=本系统,1001=用户模块第一个错误)
- 来源字母含义清晰:A=用户端(参数错/超时)、B=本系统(逻辑/数据异常)、C=第三方(调用失败)
- 编号按模块预留区间(如 1000–1999 用户模块),步长留空便于后续插入,不随组织架构变动
- 错误码不体现等级、版本、环境,这些由日志级别、监控标签、部署标识承载
错误码和提示语必须解耦
前端靠 code 做逻辑判断(跳转、重试、埋点),用户看到的是 message 的本地化结果,两者不能混用。
- 禁止在代码里拼接 message,比如 "用户 " + userId + " 不存在" —— 这无法国际化,也不利于日志归一
- message 字段保留占位符,交由 MessageSource 在运行时填充并做多语言适配
- 错误码绝不直接返回给前端展示;前端提示语(user_tip)应单独配置或由后端接口返回
- 调用第三方失败时,可转义为本系统错误码(如 B2005),但原始第三方错误码须保留在 error_detail 字段中供排查
不复杂但容易忽略。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











