为啥默认配置的spring webflux中没有异常堆栈跟踪?

Posted

技术标签:

【中文标题】为啥默认配置的spring webflux中没有异常堆栈跟踪?【英文标题】:Why there is no exception stack trace in spring webflux with default configuration?为什么默认配置的spring webflux中没有异常堆栈跟踪? 【发布时间】:2019-05-17 13:33:18 【问题描述】:

问题

我在Webflux functional programming 之后构建了一个服务器,并将以下代码添加到我的路由器:route(GET("/test/Id"), request -> throw new RuntimeException("123"))

但是当我调用/test/Id时,控制台中唯一的错误日志是:

TRACE 153036 --- [ctor-http-nio-7] o.s.w.r.function.server.RouterFunctions  : [fc7e809d] Matched org.springframework.web.reactive.function.server.RequestPredicates$$Lambda$827/1369035321@9d8c274
DEBUG 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging      : [fc7e809d] Resolved [RuntimeException: 123] for HTTP GET /test/job
TRACE 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging      : [fc7e809d] Encoding [timestamp=Mon Dec 17 15:34:43 CST 2018, path=/test/123, status=500, error=Internal Server Error, message=123]
TRACE 153036 --- [ctor-http-nio-7] o.s.w.s.adapter.HttpWebHandlerAdapter    : [fc7e809d] Completed 500 INTERNAL_SERVER_ERROR, headers=masked
TRACE 153036 --- [ctor-http-nio-7] org.springframework.web.HttpLogging      : [fc7e809d] Handling completed

没有堆栈跟踪,但是为什么呢?应该是spring或者netty处理的,不是我自定义的代码吧?设置logging.level.org.springframework.web: trace不是解决办法,日志太多了。

这是我目前发现的,但仍然感到困惑:

我查了一下为什么spring mvc有堆栈跟踪,因为tomcat中有一个log.error in try-catch,并且通过调试证明了。

那我想Netty也有这些逻辑吗?其实是has!但是让我感到困惑的是,我无法使用任何断点暂停这个 try-catch 中的代码。

这意味着可能存在一些Mono.onErrorResume 吞噬异常,因此netty 无法捕获任何东西。但我不知道如何调试大型 Mono 来检查根本原因。为什么要吞下去?

【问题讨论】:

嗨,@ToffeeLu,你可以:.doOnError(RuntimeException.class, e -> logger.error(e)) 【参考方案1】:

选项 1A:设置应用程序属性如下:

server.error.includeStacktrace=ALWAYS

选项 1B:设置应用程序属性如下:

server.error.includeStacktrace=ON_TRACE_PARAM

并且,将请求参数trace指定为true

选项 2:添加自定义 WebExceptionHandler,并确保它在组件扫描范围内。

@Component
@Order(-2)
public class LoggingErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler 
    private static final Logger logger = LoggerFactory.getLogger(LoggingErrorWebExceptionHandler.class);

    public LoggingErrorWebExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
            ServerProperties serverProperties, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer) 
        super(errorAttributes, resourceProperties, serverProperties.getError(), applicationContext);
        super.setMessageWriters(serverCodecConfigurer.getWriters());
        super.setMessageReaders(serverCodecConfigurer.getReaders());
    

    @Override
    protected void logError(ServerRequest request, HttpStatus errorStatus) 
        Throwable ex = getError(request);
        logger.error("Error Occurred:", ex);
        super.logError(request, errorStatus);
    


更多详情请见https://www.baeldung.com/spring-webflux-errors。

【讨论】:

第二个是变通办法,如果没有其他解决办法,我们只好用这个CustomizedExceptionHandler

以上是关于为啥默认配置的spring webflux中没有异常堆栈跟踪?的主要内容,如果未能解决你的问题,请参考以下文章

为啥spring webflux默认选择jetty然后失败?

Spring Boot 自动配置的 Jackson ObjectMapper 默认不用于 WebFlux WebClient

为啥 Spring WebFlux 应用程序不支持 @RestController 映射前缀?

如何在没有 spring-boot 的情况下在 spring-webflux 中加载配置?

为啥使用 webflux 进行 spring boot 测试会忽略自定义 jackson 模块

如何为 Spring WebFlux 配置 netty 连接超时