Когда не нужно бросать исключения

В статьях “Исключения для исключительных ситуаций” и “3 задачи валидации” я описал ситуации, в которых не стоит использовать исключения.

Но в каких ситуациях можно и нужно использовать исключения?

Две причины для исключений

Исключения у меня могут быть выброшены в двух случаях:

Причина 1. Отъехала инфраструктура.

Не можем нормально обработать запрос, поэтому падаем.

Примеры: упала БД, нет места на диске, не отвечает критичное для выполнения запроса внешнее API.

Причина 2. Ошибка в коде приводит к некорректному поведению.

Например пытаемся найти счёт пользователя, счёт всегда должен быть а его в базе не нашли, или например пытаемся списать со счëта отрицательную сумму.

Тут очевидно что проблема в некорректном коде. Поэтому мы должны упасть чтобы разработчики узнали о проблеме.

Неважно, фронт ошибся или бек, в любом случае стоит исправить ошибку.

Во всех остальных ситуациях исключения быть не должно.

Баг или валидация не прошла?

Важно не перепутать проверки в коде на логичность происходящего (защиту от багов) с проверками входящих данных от пользователя, то есть валидацией.

Проверив данные полученные от пользователя мы должны сообщить ему какие поля он ввёл неправильно. Исключение здесь не требуется.

Если же не прошла проверка где-то “под капотом”, когда мы уже всю валидацию выполнили выше, то это свидетельствует о том что в нашем коде есть ошибки. Поэтому обязательно бросаем исключение.

Не смешивать

Если у вас код проверки входящих данных от пользователя и код проверок на корректность данных или операций в самом приложении объединён каким-то образом, то придётся его разделить.

Отдельно будет проверяться ввод пользователя (без исключений) и отдельно будут проверки на целостность данных и логичность действий (с исключениями).

Вы можете опасаться того что возникнет дублирование, но назначение у тех и других проверок разное, поэтому разделять можно и нужно.

Бросили, что дальше?

Дальше наше приложение упало. Перехватывать исключение и пытаться “исправить ошибку” не стоит.

Допустимо перехватывать исключения из стороннего кода, если там разработчик ошибся и использовал исключение для передачи информации.

В своём коде исключение должно просто прерывать выполнение и отдавать код ошибки пользователю. Вероятно ещё и залогировать информацию об ошибке, для отладки и мониторинга.

Никакого перехвата с обработкой и дальнейшим выполнением логики быть не должно.

Мониторинг ошибок

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

Каждое исключение в веб-приложении по умолчанию возвращает код ошибки HTTP 500.

Поэтому, отслеживая коды ответа HTTP в нашем приложении, мы сразу увидим, есть ли у нас ошибки, сколько их, а также увеличивается или уменьшается их количество со временем.

Например, вы залили код и не заметили ошибку. Это сразу станет видно на графике, и вы легко обнаружите и исправите ошибку. Возможно, ещё до того, как пользователи придут с жалобами.