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

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

Intereting Posts
Как я могу определить, является ли число 10 в Котлине или Яве? Kotlin – заводская функция для класса с частным конструктором Этот тип имеет конструктор и должен быть инициализирован здесь – Kotlin Несоответствие дженериков Котлина в иерархии классов Android / Kotlin читает файл с помощью Java.io.File: проблема с дорогой Не удалось уменьшить список логических элементов в kotlin Kotlin для assertThat (foo, instanceOf (Bar.class)) Kotlin: одно свойство с несколькими сеттерами разных типов Kotlin и Jack не поддерживаются (Android Studio 2.3.2) Конфигурация проекта котла в Gradle с помощью Gradle Script Kotlin android.support.v4.app.FragmentManager не может быть предоставлен без @ Provides- или @ Produces-аннотированного метода Преобразование наблюдаемого в текущее с противодавлением в RxJava2 Kotlin не может идентифицировать параметры, если явно не указано Java 2-минутная задержка иногда при подключении сокета? Переопределяющая переменная создает NPE, когда переменная используется при инициализации в суперклассе