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

如何正确处理SpringBoot异常,避免其冒泡至服务器日志?

问题:SpringBoot自定义异常处理后WildFly仍记录DEBUG日志

我有一个RestController会抛出自定义异常BoogyException,该异常继承自RuntimeException。

RestController代码:

@RestController
public class Test {
    @GetMapping(path = "/test")    
    public ResponseEntity<String> myTest() {
       throw new BoogyException("I am a boog exception.");
    }
}

BoogyException代码:

public class BoogyException extends RuntimeException {
    public BoogyException(Exception exception) {
      // 省略实现
    }
}

我通过@RestControllerAdvice类映射BoogyException并返回ResponseEntity:

@RestControllerAdvice
public class MotherExceptionHandler {

    @ExceptionHandler(value = { BoogyException.class})
    public ResponseEntity<MyJsonExcp> handleBoogyException(final Exception ex) {
           // 省略实现
    }
}

MyJsonExcp是带有Jackson注解的简单POJO。当RestController抛出BoogyException时,我能得到正确的JSON格式响应,但WildFly服务器日志中仍会记录一条DEBUG级别的RuntimeException:

DEBUG [io.undertow.request.error-response] (default task-2) 
    Setting error code 500 for exchange HttpServerExchange{ GET /api/test
    request {cache-control=[max-age=0], accept-encoding=[gzip, deflate, br], 
    ... X-Frame-Options=[SAMEORIGIN]}}: java.lang.RuntimeException
        at io.undertow.server.HttpServerExchange.setStatusCode(HttpServerExchange.java:1410)
        ...(省略后续栈跟踪)

看起来SpringBoot将我的自定义异常作为RuntimeException冒泡到了服务器日志中,请问有没有办法阻止这种情况?(使用SpringBoot 2.7.0版本)


解决方案

1. 修正异常处理器的参数与状态码设置

将异常处理器的参数改为具体的BoogyException,同时设置明确的业务状态码(避免默认的500触发Undertow的错误日志),明确告知Spring该异常已被完全处理:

@ExceptionHandler(BoogyException.class)
public ResponseEntity<MyJsonExcp> handleBoogyException(final BoogyException ex) {
    MyJsonExcp errorResponse = new MyJsonExcp();
    errorResponse.setMessage(ex.getMessage());
    // 根据业务场景设置合适的状态码,比如400(Bad Request)
    return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}

2. 补充自定义异常的构造方法

当前BoogyException仅实现了接收Exception的构造方法,但代码中抛出的是带字符串消息的实例,需要补充对应构造方法避免异常包装问题:

public class BoogyException extends RuntimeException {
    public BoogyException(String message) {
        super(message);
    }

    public BoogyException(Exception exception) {
        super(exception);
    }
}

3. 调整Undertow的日志级别

如果确认异常已被正确处理,只是Undertow的DEBUG日志冗余,可以在application.properties中修改对应日志的级别,避免记录这类调试信息:

logging.level.io.undertow.request.error-response=INFO

4. 清除请求中的异常标记

如果上述方法无效,可以在异常处理器中手动清除请求上下文的异常,阻止Undertow感知到未处理异常:

@ExceptionHandler(BoogyException.class)
public ResponseEntity<MyJsonExcp> handleBoogyException(final BoogyException ex, HttpServletRequest request) {
    MyJsonExcp errorResponse = new MyJsonExcp();
    errorResponse.setMessage(ex.getMessage());
    // 清除请求中的异常记录
    request.setAttribute("javax.servlet.error.exception", null);
    return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:03:21