我遇到了Spring(和kotlin?)的问题,我的全局错误处理程序没有捕获自定义转换器中抛出的任何异常。
我知道spring默认支持string-> UUID映射,但我想明确检查是否实际抛出了异常。这是以下转换器。无论是否有我自己的转换器实现,行为都是一样的。
我的WebMvcConfuguration如下所示:
using Swashbuckle.Application;
[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
namespace NEOH.Api
{
public class SwaggerConfig
{
public static void Register()
{
这是我的GlobalExceptionHandler: (它还包含其他处理程序,为简洁起见我省略了)
@Configuration
class WebMvcConfiguration : WebMvcConfigurerAdapter() {
override fun addFormatters(registry: FormatterRegistry) {
super.addFormatters(registry)
registry.addConverter(Converter<String, UUID> { str ->
try {
UUID.fromString(str)
} catch(e: IllegalArgumentException){
throw RuntimeException(e)
}
})
}
最后,控制器:
@ControllerAdvice
class GlobalExceptionHandler : ResponseEntityExceptionHandler() {
@ExceptionHandler(Exception::class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
fun handleException(ex: Exception): ApiError {
logger.info(ex.message, ex)
return ApiError(ex.message)
}
}
控制器内部的异常(例如NotImplementedError)方法被捕获得很好。但吞下无效UUID时在转换器中抛出的IllegalArgumentException,并且spring返回空400响应。
我现在的问题是:如何捕获这些错误并回复自定义错误消息?
提前致谢!
答案 0 :(得分:1)
我遇到了同样的问题。 Spring吞噬了任何IllegalArgumentException
(在我的情况下为ConversionFailedException
)。
获得我正在寻找的行为;即,只处理列出的例外并使用其他例外的默认行为,您不得扩展ResponseEntityExceptionHandler
。
示例:
@ControllerAdvice
public class RestResponseEntityExceptionHandler{
@ExceptionHandler(value = {NotFoundException.class})
public ResponseEntity<Object> handleNotFound(NotFoundException e, WebRequest request){
return new ResponseEntity<>(e.getMessage(), new HttpHeaders(), HttpStatus.NOT_FOUND);
}
}
答案 1 :(得分:0)
经过一些试验和错误后,我找到了一个解决方案:
不是使用@ControllerAdvice
,而是实现其他人继承的BaseController并添加异常处理程序。
所以我的Base控制器看起来像这样:
abstract class ApiBaseController{
@ExceptionHandler(Exception::class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
fun handleException(ex: Exception): ApiError {
return ApiError(ex.message)
}
}
如果有人可以详细说明它为什么会这样,而不是其他方式,请这样做,我会将你的答案标记为已接受。
答案 2 :(得分:0)
我从@ georg-moser检查了解决方案。起初,它看起来不错,但看起来它还包含另一个问题。它将所有异常转换为HTTP代码500 ,这不是人们一直想要的。
相反,我决定从handleExceptionInternal
覆盖ResponseEntityExceptionHandler
方法。
在我的情况下,记录错误已足够,所以我得出以下结论:
@Override
@NonNull
protected ResponseEntity<Object> handleExceptionInternal(@Nonnull final Exception e,
final Object body,
final HttpHeaders headers,
final HttpStatus status,
@Nonnull final WebRequest request) {
final ResponseEntity<Object> responseEntity = super.handleExceptionInternal(e, body, headers, status, request);
logGenericException(e);
return responseEntity;
}
希望对您有帮助!