Java自定义异常无法跨服务传递错误码,必须通过HTTP响应体显式返回结构化JSON(如{"code":1001,"msg":"库存不足"}),由调用方解析code字段;服务间只依赖API约定,不传递Java异常对象。

在微服务中,Java 自定义异常本身不会自动跨服务传递错误码——因为异常对象无法直接序列化穿透 HTTP 或 RPC 边界。真正传递的是你主动设计的结构化错误响应(如 JSON),错误码需显式放入响应体,并由调用方解析。关键不在“抛出什么异常”,而在于“如何统一约定并透出错误码”。
自定义异常只在本服务内使用
你在服务 A 中定义的 BusinessException extends RuntimeException,仅用于本服务内部流程控制和日志记录。它不会、也不该被序列化传到服务 B。微服务间通信是面向 API 的,不是面向 Java 对象的。
- 服务 A 接收到请求后,业务逻辑中 throw
BusinessException(1001, "库存不足")</li> <li>全局异常处理器(如 <code>@ControllerAdvice
)捕获它,转为标准响应格式(如{"code":1001,"msg":"库存不足","data":null}) - 这个 JSON 响应通过 HTTP 返回给调用方(可能是网关、前端,或其他微服务)
错误码必须通过响应体显式返回
下游服务(或前端)拿到的是 HTTP 响应体里的 JSON,不是 Java 异常。所以错误码必须作为字段写进响应结构里,常见做法:
- 统一响应类:定义
Result<t></t>,含int code、String msg、T data - HTTP 状态码配合业务码:例如所有业务异常都返回 HTTP 200,靠
code区分;或对严重错误用 4xx/5xx(如参数错用 400,系统异常用 500),再用code细分业务场景 - 避免把错误码藏在 response header 或自定义协议头里——不易维护、不通用、SDK 难适配
跨服务调用时,消费方要解析响应体取错误码
当服务 B 调用服务 A 的接口,不能 try-catch 服务 A 的自定义异常。它只能解析返回的 JSON,检查 code 字段做分支处理:
立即学习“Java免费学习笔记(深入)”;
- 用 OpenFeign 时,可通过
ErrorDecoder拦截 4xx/5xx 响应,提取 body 中的code,再手动 throw 本地对应的异常(如InventoryException(code)) - 用 RestTemplate 时,在
ResponseEntity<result></result>中判断result.getCode() != 0,然后根据 code 构造本地异常或直接处理 - 关键是:服务 B 的异常类型和服务 A 完全无关,它只依赖 API 文档约定的
code含义
推荐实践:错误码中心化管理 + 响应规范强制约束
避免每个服务各自定义一版错误码,导致调用方难以适配。建议:
- 建立共享模块(如
common-error),定义枚举ErrorCode:包含code、message、level(如业务/系统/参数) - 所有服务的全局异常处理器,都基于该枚举构造响应,确保相同含义的错误码全局唯一
- API 文档(如 Swagger/YAML)明确标注每个接口可能返回的
code及含义,供调用方查阅 - 网关层可做简单错误码透传或统一封装,但不建议在网关里做业务逻辑判断
不复杂但容易忽略:错误码不是靠异常“飞过去”的,而是靠人设计、靠协议带过去、靠双方约定好怎么读。


















