You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何已处理的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仅负责捕获异常并返回自定义响应,不会阻止异常在抛出路径上被其他日志组件记录。

解决方法

  1. 检查业务代码的日志逻辑:查看ExampleResource的exampleMethod方法,确认是否在抛出ResponseStatusException前手动记录了ERROR级日志。如果有,可根据需求调整日志级别(比如改为WARN或INFO),或者移除不必要的日志记录。
  2. 配置日志框架过滤规则:如果是AOP或框架自动记录的日志,可以通过日志配置文件(如logback.xml、log4j2.xml)将目标类的日志级别调低。例如在logback中添加:
    <logger name="org.example.ExampleResource" level="WARN" />
    
    这样ERROR级别的ResponseStatusException日志就不会被输出。
  3. 控制异常处理器的日志行为:Spring的handleExceptionInternal方法默认会记录WARN级日志,若日志框架配置导致级别被升级,可重写该方法,或在异常处理器中显式控制日志输出,避免重复记录。

内容的提问来源于stack exchange,提问作者ba9c83134a187bb4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:39:57