Spring Framework проглатывает исключение пользовательских преобразователей

Я столкнулся с проблемой с Spring (и kotlin?), Где мои глобальные обработчики ошибок не улавливают никаких исключений, создаваемых в пользовательском конвертере.

Я знаю, что весна поддерживает string-> UUID-сопоставление по умолчанию, но я хочу явно проверить, действительно ли исключено исключение. Который является следующим преобразователем. Поведение такое же, как и без моей реализации конвертера.

Моя WebMvcConfuguration выглядит следующим образом:

@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) } }) } 

И это мой GlobalExceptionHandler: (он также содержит другие обработчики, которые я пропустил для краткости)

 @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) } } 

И, наконец, контроллер:

 @Controller class MyController : ApiBaseController() { @GetMapping("/something/{id}") fun getSomething(@PathVariable("id") id: UUID) { throw NotImplementedError() } } - @Controller class MyController : ApiBaseController() { @GetMapping("/something/{id}") fun getSomething(@PathVariable("id") id: UUID) { throw NotImplementedError() } } 

Исключения внутри контроллера (например, NotImplementedError) методы пойманы просто отлично. Но исключение IllegalArgumentException, содержащееся в конвертере, когда недопустимые UUID переданы, проглатывается, а весна возвращает пустой ответ 400.

Теперь мой вопрос: как я могу поймать эти ошибки и ответить специальным сообщением об ошибке?

Заранее спасибо!

У меня такая же проблема. Spring проглотил любое IllegalArgumentException ( 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); } } 

После нескольких проб и ошибок я нашел решение:

Вместо использования @ControllerAdvice , реализация BaseController, которую другие наследуют и добавляет обработчики исключений, работает.

Итак, мой базовый контроллер выглядит так:

 abstract class ApiBaseController{ @ExceptionHandler(Exception::class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody fun handleException(ex: Exception): ApiError { return ApiError(ex.message) } } 

Если кто-то может уточнить, почему это работает так, а не наоборот, сделайте это, и я помету ваш ответ как принятый.