Spring Boot
Теория: Обработка ошибок
Во время работы приложения могут возникать ошибки, которые должны транслироваться в правильные коды ответа. Всего в Spring можно выделить две большие группы ошибок:
- Ошибки внутри Spring Boot — это исключения, которые фреймворк генерирует в ответ на разные ситуации
- Ошибки в коде приложения — это исключения, которые возникают в нашем коде или коде библиотек внутри нашего кода
Рассмотрим каждую группу отдельно.
Исключения Spring Boot
Взаимодействие с внешней средой непредсказуемо. Всегда есть вероятность получить несоответствие между ожиданиями Spring Boot и реальностью. Обычно это проявляется в неправильно сформированных HTTP-запросах. Представим, что у нас есть такой обработчик:
Что будет, если мы выполним запрос с параметром limit, передав туда строку? В ответ мы получим ошибку 400, которая указывает на «плохой запрос»:
Эту ситуацию Spring Boot обрабатывает внутри себя. Точно так же он обрабатывает и множество других ситуаций, среди которых:
- Используется неподдерживаемый HTTP-метод
- Используется неподдерживаемый media type
- Параметры обработчика не проходят валидацию
Всего есть около 15 ошибок-исключений. Каждое исключение обрабатывается автоматически. После обработки мы получаем соответствующий HTTP-код и тело с описанием ошибки:
Обработкой этих ошибок в Spring Boot занимается класс ResponseEntityExceptionHandler. Он вызывается автоматически для обработки любых ошибок, возникающих во время обработки маршрута (диспетчеризации). Причем это работает не только для кода самого Spring Boot, но и для кода внутри обработчика.
Чтобы лучше понять обработку ошибок, советуем открыть исходники класса ResponseEntityExceptionHandler и изучить их.
Ошибки в коде приложения
Если ничего специально не делать, то любые ошибки внутри кода приложения будут автоматически приводиться к HTTP-коду 500. Для большинства ошибок это желаемое поведение, но иногда нужна и особая обработка. Например, важно выдать ошибку 404, когда запись в базе данных не найдена.
Посмотрим, что произойдет в коде ниже, если данных в базе нет:
В этом случае вернется ошибка с кодом 500. С точки зрения HTTP, это неверное поведение. В этом случае правильный код возврата — 404. Технически мы можем вернуть код 404 с помощью ResponseEntity. Нам понадобится метод ResponseEntity.of(). Он принимает на вход Optional и возвращает коды 200 или 404 в зависимости от того, есть результат или нет:
Но бывают и более сложные ситуации, в которых одним таким методом не обойтись. Например, мы не всегда имеем дело с Optional, иногда требуется дополнительная логика для формирования ответа. В таких ситуациях, удобнее определить свой обработчик ошибки на базе ResponseEntityExceptionHandler.
Для централизованной обработки ошибки 404 нужно выполнить три шага.
Шаг 1. Создать исключение:
Шаг 2. Реализовать глобальный обработчик этого исключения:
Чтобы Spring Boot начал использовать наш обработчик ошибок для всех контроллеров сразу, нужно использовать несколько аннотаций:
@ControllerAdviceуказывает, что этот класс отвечает за централизованную обработку исключений@ExceptionHandlerуказывает, какое исключение должно обрабатываться проаннотированным методом
Сам метод похож на обычный обработчик маршрута. Разница только в том, что ему на вход подается возникшее исключение. Далее мы сами описываем логику и возвращаем ResponseEntity с правильным кодом и телом ответа.
Шаг 3. Внедрить использование исключения в обработчики маршрутов:



