【问题标题】:Spring ApplicationListener throwing RuntimeException not caught by @ControllerAdviceSpring ApplicationListener 抛出 RuntimeException 未被@ControllerAdvice 捕获
【发布时间】:2019-01-15 01:09:25
【问题描述】:

我们使用的是刚刚从 1.4 范围更新的 Spring Boot 2.x。在 ApplicationListener 监听自定义 ApplicationEvent 之前,我们会抛出 RuntimeException ,我们的 React.js UI 将返回 JSON 并在字符串中显示错误消息。我们添加了 ExceptionHandler@ControllerAdvice 来修复可能引发异常的正常请求/响应路径,以便 UI 将其作为 JSON 接收并显示适当的 UI 错误对话框和漂亮的消息。很多时候,该消息只是我们放入抛出的异常中的消息字符串。

然而,在我们的ApplicationListener 代码中抛出了一个RuntimeException,我们在其中放入了一个不错的消息字符串。 UI 没有收到此响应/JSON,而是一个简单的 HttpStatus 500 和一个通用的“内部服务器错误”字符串。绝对不是我们放入异常中的漂亮字符串。

这适用于 Spring Boot 1.x,但不再适用于 Spring Boot 2.0

这是监听器中的抛出代码。

throw new RuntimeException("Your account is locked out. Please check your email for reset instructions.");

这是通用Exception 的代码。我也尝试过用RuntimeException注释的不同名称的相同方法,但这也不起作用。下面的代码还显示将状态设置为 INTERNAL_SERVER_ERROR。但我已将其更改为其他内容,并且在侦听器中抛出的 RuntimeException 仍然是 500 状态,并且在此方法中设置断点表明它不会因为侦听器中抛出的异常而被调用。

@ExceptionHandler(Exception.class)
ResponseEntity<Object> handleGeneralExceptions(Exception ex, HttpServletResponse response) throws IOException {
    LOGGER.error("",ex);
    return getErrorResponse(ex,
            null,
            HttpStatus.INTERNAL_SERVER_ERROR,
            ex.getMessage(),
            response
    );
}

【问题讨论】:

  • 添加完整课程。如何使用@controller 建议
  • sajib 没必要。这里的关键是这是一个抛出 RuntimeException 的 Listener,所以它由 Spring 的 RequestMappingHandlerAdapter 处理,这与在 Service 类或线程路径中抛出的 Exception 完全不同。

标签: spring-boot spring-rest


【解决方案1】:

我的一个队友解决了这个问题。

第一个只有监听器,只有那些与 Spring Security AuthenticationEvent相关的监听器

我们为它添加了一个新的Exception 类和一个Serializer

我们也有一个

static class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

并在config()方法中添加

 .exceptionTranslator(exception -> {
     if (exception instanceof OAuth2Exception) {
         OAuth2Exception oAuth2Exception = (OAuth2Exception) exception;
         return ResponseEntity.status(oAuth2Exception.getHttpErrorCode())
                              .body(new CustomOauthException(oAuth2Exception.getMessage()));
     } else {
         throw exception;
     }
 })

【讨论】:

    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 2012-12-09
    • 2020-08-04
    • 1970-01-01
    • 2012-06-06
    相关资源
    最近更新 更多