Spring Boot 2.1:在 WebMvcConfigurer#addFormatters(...) 中抛出的异常未在 @RestControllerAdvice 中捕获
Spring Boot 2.1 : Exception thrown in WebMvcConfigurer#addFormatters(...) not catched in @RestControllerAdvice
从 Spring Boot 2.0 更新到 2.1 后,WebMvcConfigurer#addFormatters( FormatterRegistry registry )
中抛出的所有异常都不再在 @RestControllerAdvice
中捕获。我将此方法用于其他转换器。
例如:
public class ConvertersContainer {
public static class StringToStatusConverter implements Converter<String, Status> {
@Override
public Status convert( String source ) {
return Status.findStatus( source );
}
}
}
而 Status
是一个枚举。
public enum Status {
HAPPY("happy"), ANGRY("angry");
private String title;
public static Status findStatus( final String title) {
return stream( values() )
.filter( status-> status.getTitle().equals( title) )
.findFirst()
.orElseThrow( () -> new StatusNotFoundException( "...." ) );
}
}
和StatusNotFoundException extends RuntimeException {}
我是这样注册这个转换器的:
@Configuration
public class ConverterRegister implements WebMvcConfigurer {
@Override
public void addFormatters( FormatterRegistry registry ) {
registry.addConverter( new ConvertersContainer.StringToStatusConverter() );
WebMvcConfigurer.super.addFormatters( registry );
}
}
控制器通知:
@RestControllerAdvice
public class Advice {
@ExceptionHandler( StatusNotFoundException .class)
protected String handleStatusNotFoundException(StatusNotFoundException ex) { ... }
}
当我设置断点时,方法 Status#findStatus(...)
执行良好,但从未在 @RestControllerAdvice
中捕获异常。我究竟做错了什么?
非常感谢
似乎 Spring 包装了转换过程中抛出的所有异常并抛出 org.springframework.beans.TypeMismatchException
而不是用户自定义的异常。
在我看来这种行为是不正常的,如果在转换过程中抛出异常,这个异常应该优先于所有框架的异常。所以要解决这个问题,我们必须 extends ResponseEntityExceptionHandler
并覆盖它的 protected ResponseEntity<Object> handleTypeMismatch(...)
。
谢谢@Eric(他评论了上面的问题)。
从 Spring Boot 2.0 更新到 2.1 后,WebMvcConfigurer#addFormatters( FormatterRegistry registry )
中抛出的所有异常都不再在 @RestControllerAdvice
中捕获。我将此方法用于其他转换器。
例如:
public class ConvertersContainer {
public static class StringToStatusConverter implements Converter<String, Status> {
@Override
public Status convert( String source ) {
return Status.findStatus( source );
}
}
}
而 Status
是一个枚举。
public enum Status {
HAPPY("happy"), ANGRY("angry");
private String title;
public static Status findStatus( final String title) {
return stream( values() )
.filter( status-> status.getTitle().equals( title) )
.findFirst()
.orElseThrow( () -> new StatusNotFoundException( "...." ) );
}
}
和StatusNotFoundException extends RuntimeException {}
我是这样注册这个转换器的:
@Configuration
public class ConverterRegister implements WebMvcConfigurer {
@Override
public void addFormatters( FormatterRegistry registry ) {
registry.addConverter( new ConvertersContainer.StringToStatusConverter() );
WebMvcConfigurer.super.addFormatters( registry );
}
}
控制器通知:
@RestControllerAdvice
public class Advice {
@ExceptionHandler( StatusNotFoundException .class)
protected String handleStatusNotFoundException(StatusNotFoundException ex) { ... }
}
当我设置断点时,方法 Status#findStatus(...)
执行良好,但从未在 @RestControllerAdvice
中捕获异常。我究竟做错了什么?
非常感谢
似乎 Spring 包装了转换过程中抛出的所有异常并抛出 org.springframework.beans.TypeMismatchException
而不是用户自定义的异常。
在我看来这种行为是不正常的,如果在转换过程中抛出异常,这个异常应该优先于所有框架的异常。所以要解决这个问题,我们必须 extends ResponseEntityExceptionHandler
并覆盖它的 protected ResponseEntity<Object> handleTypeMismatch(...)
。
谢谢@Eric(他评论了上面的问题)。