Spring ApplicationListener 抛出 RuntimeException 未被 @ControllerAdvice 捕获
Spring ApplicationListener throwing RuntimeException not caught by @ControllerAdvice
我们正在使用 Spring 引导 2.x 刚刚从 1.4 范围更新。在 ApplicationListener
监听自定义 ApplicationEvent
之前,我们会抛出一个 RuntimeException
,我们的 React.js UI 会得到 JSON 返回错误消息在字符串中。我们添加了一个 ExceptionHandler
和 @ControllerAdvice
来修复可能抛出异常的正常 Request/Response 路径,这样 UI 就会将其接收为 JSON 并显示适当的 UI 带有漂亮消息的错误对话框。很多时候,该消息只是我们放入抛出的异常中的消息字符串。
但是,在我们的 ApplicationListener
代码中抛出 RuntimeException
并且我们在其中放置了一个很好的消息字符串。 UI 没有收到这个 response/JSON,而是一个简单的 HttpStatus 500 和一个通用的 "Internal Server Error" 字符串。绝对不是我们放入异常的漂亮字符串。
这适用于 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
);
}
我的一个队友解决了这个问题。
1st 只有听众,并且只有那些与 Spring 安全相关的 AuthenticationEvent
我们为其添加了一个新的 Exception
class 和一个 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;
}
})
我们正在使用 Spring 引导 2.x 刚刚从 1.4 范围更新。在 ApplicationListener
监听自定义 ApplicationEvent
之前,我们会抛出一个 RuntimeException
,我们的 React.js UI 会得到 JSON 返回错误消息在字符串中。我们添加了一个 ExceptionHandler
和 @ControllerAdvice
来修复可能抛出异常的正常 Request/Response 路径,这样 UI 就会将其接收为 JSON 并显示适当的 UI 带有漂亮消息的错误对话框。很多时候,该消息只是我们放入抛出的异常中的消息字符串。
但是,在我们的 ApplicationListener
代码中抛出 RuntimeException
并且我们在其中放置了一个很好的消息字符串。 UI 没有收到这个 response/JSON,而是一个简单的 HttpStatus 500 和一个通用的 "Internal Server Error" 字符串。绝对不是我们放入异常的漂亮字符串。
这适用于 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
);
}
我的一个队友解决了这个问题。
1st 只有听众,并且只有那些与 Spring 安全相关的 AuthenticationEvent
我们为其添加了一个新的 Exception
class 和一个 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;
}
})