为何已处理的ResponseStatusException仍被Spring记录堆栈跟踪?
已处理ResponseStatusException仍打印ERROR级堆栈日志的原因及解决
问题描述
我的代码库分为控制器层与服务层,遇到无法找到实体这类不可恢复错误时,会从服务层抛出携带HTTP 404状态码的ResponseStatusException。我配置了Controller Advice,其中包含针对该异常的ExceptionHandler,用来生成并返回自定义响应。
但即便异常已被处理,日志中仍会输出ERROR级别的堆栈跟踪信息:
2023-11-07T08:38:23.763+01:00 ERROR 2618932 --- [nio-8080-exec-8] org.example.ExampleResource : Exception in exampleMethod() with cause = 'NULL' and exception = '404 NOT_FOUND "dd"' org.springframework.web.server.ResponseStatusException: 404 NOT_FOUND "entity not found!" at org.example.ExampleResource.exampleMethod(ExampleResource.java:81) ~[main/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.7.jar:6.0.7]
我的Controller Advice异常处理器代码如下:
@ResponseBody @ExceptionHandler(value = {ResponseStatusException.class}) protected ResponseEntity<Object> responseStatusExceptionHandler(ResponseStatusException exception, WebRequest request) { return handleExceptionInternal(exception, buildResponseBody(exception.getReason(), request, httpCodeToStatus(exception.getStatusCode())), new HttpHeaders(), exception.getStatusCode(), request); }
为什么异常已经被处理,还是会生成这条ERROR级的堆栈日志?
原因分析
这条ERROR日志并不是由Spring全局异常处理器输出的,而是你的控制器(ExampleResource)本身在抛出异常时记录的日志。从日志的类名可以看出,日志输出方是org.example.ExampleResource,说明你的控制器方法里可能存在以下情况:
- 手动通过
try-catch捕获异常后,抛出ResponseStatusException的同时用ERROR级别记录了日志; - 使用了AOP切面、日志拦截器等组件,在方法执行抛出异常时自动记录了ERROR级日志。
另外,Spring的@ExceptionHandler仅负责捕获异常并返回自定义响应,不会阻止异常在抛出路径上被其他日志组件记录。
解决方法
- 检查业务代码的日志逻辑:查看
ExampleResource的exampleMethod方法,确认是否在抛出ResponseStatusException前手动记录了ERROR级日志。如果有,可根据需求调整日志级别(比如改为WARN或INFO),或者移除不必要的日志记录。 - 配置日志框架过滤规则:如果是AOP或框架自动记录的日志,可以通过日志配置文件(如logback.xml、log4j2.xml)将目标类的日志级别调低。例如在logback中添加:
这样ERROR级别的<logger name="org.example.ExampleResource" level="WARN" />ResponseStatusException日志就不会被输出。 - 控制异常处理器的日志行为:Spring的
handleExceptionInternal方法默认会记录WARN级日志,若日志框架配置导致级别被升级,可重写该方法,或在异常处理器中显式控制日志输出,避免重复记录。
内容的提问来源于stack exchange,提问作者ba9c83134a187bb4
相关产品推荐
相关产品推荐

