Spring Boot全局异常处理器返回400,但某特定客户端调用时Filter仍返回500
1. 系统环境
- 框架: Spring Boot REST API(基于servlet)。
全局异常处理器:
- 使用
@RestControllerAdvice
捕获MyOperationException
。 - 返回带有HTTP 400和自定义错误体的
ResponseEntity
。
- 使用
强制Filter:
RuleVerifierFilter
(无法修改,来自其他团队)。- 用try-catch包裹整个filter chain,任何异常都会设置响应为500。
2. 正常异常处理流程
- 当
MyService.downloadByKey
抛出MyOperationException
时,会被全局异常处理器捕获。 - 处理器会记录异常日志并返回预期的
ResponseEntity
。 对于大多数客户端(如Postman、RestTemplate),表现正常:
- 客户端收到带有HTTP 400的自定义错误响应。
3. 问题场景
- 触发条件: 仅当某个特定上游团队调用API时才会出现。
实际表现:
- 全局异常处理器返回后,异常依然被
RuleVerifierFilter
捕获。 - 客户端收到500错误,而不是预期的400。
- 响应体内容如下:
{"error": "Request processing failed; nested exception is com.mycompany.myproject.exception.exceptions.MyOperationException"}
- 连接没有被提前关闭,客户端能收到完整响应体。
- 全局异常处理器返回后,异常依然被
期望与实际行为对比
场景 | 期望行为 | 实际行为(某特定客户端) |
---|---|---|
controller抛出异常 | 全局异常处理器返回HTTP 400和自定义错误体 | 异常继续传播到RuleVerifierFilter ,最终返回HTTP 500和通用错误体 |
客户端收到 | HTTP 400,自定义错误JSON | HTTP 500,错误JSON中包含嵌套异常信息 |
正常工作的客户端 | Postman、RestTemplate、其他非特定客户端 | 只有某个特定客户端会出现该问题 |
4. 日志证据
- 日志中显示有
NestedServletException
包裹了MyOperationException
。 - 堆栈信息中既有controller也有
RuleVerifierFilter
。 - 说明异常在处理器之后仍然向上传递,被filter捕获。
5. 已尝试的排查步骤
- 已确认全局异常处理器被调用并正确构建了响应。
- 已验证只有某个特定客户端会复现,其他客户端无法复现。
- 本地尝试复现未成功。
6. 仍有疑问
- 为什么异常在被全局异常处理器处理后还会传递到filter?
- 为什么只有某个特定客户端会出现这个问题?
- 如何确保异常被处理后不会再向上传递到filter?
- 还有哪些排查方向或调试建议?