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

Классификация ошибок

Давайте начнем разговор с описания классификаций ошибок, с которыми обычно сталкиваются API:

  • Бизнес-ошибки — ошибки, вызванные ожидаемыми случаями.
  • Системные ошибки — ошибки, вызванные непредвиденными случаями.

Бизнес-ошибки возникают, когда программа не может продолжить выполнение из-за ожидаемого состояния ошибки. Это могут быть ошибки проверки или какой-либо другой случай, когда бизнес-логика указывает, что поток не может продолжаться.

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

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

Исключения

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

Когда мы работаем с ошибками, которые, как мы знаем, произойдут (т. е. когда мы выбрасываем исключение), мы должны разрешать выбрасывать базу BusinessException. Есть несколько примеров того, как получить больше детализации, например, расширение этого исключения для пользовательских исключений или расширение базового класса Exception для включения «кодов ошибок». Лично я бы предпочел расширить класс Exception, включив в него код ошибки, потому что он переходит в удобочитаемые ответы при возврате их вызывающей стороне.

Вы можете включить другие исключения по умолчанию в ту же категорию, что и BusinessException. Например, NullArgumentException — это распространенный тип ошибки, когда вам имеет смысл продолжать его использовать. Я бы посоветовал свести количество таких исключений к минимуму, потому что поддержка большого количества исключений может быть обременительной, и это не имеет большого значения, когда речь идет о Rest API.

Все остальные исключения относятся к случаю системной ошибки. Это может быть DbException, ConcurrentException или любое другое необработанное исключение. Эти типы исключений могут попасть в вызывающую структуру без обработки. Это не означает, что с ними можно обращаться и/или преобразовывать в BusinessExceptions.

Когда использовать исключения

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

Например, один из наиболее распространенных случаев, когда исключение не следует использовать, — это когда вызывающая сторона запрашивает несуществующую запись БД. Мы можем вернуть либо null, либо необязательное значение в качестве результата вместо того, чтобы выдавать ошибку.

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

Распространение ошибок

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

Правило 1: Не перехватывайте исключения, которые вы не обрабатываете.

Это также известно как «проглатывание исключений». Это означает, что вы перехватываете исключение и ничего с ним не делаете. Пусть исключение всплывает до тех пор, пока его можно будет обработать или оно должно выйти за пределы службы во внешнюю систему.

Правило 2: Не делайте исключение из журнала и не перебрасывайте.

Честно говоря, это всего лишь Правило 1, но оно настолько серьезное, что требует отдельного правила. Пусть обработчик занимается регистрацией соответствующего сообщения.

Правило 3: поймать самое конкретное возможное исключение

Когда вы решите поймать исключение, поймайте наиболее конкретное возможное исключение. Это уменьшит вероятность того, что вы можете обработать неправильное исключение.

Правило 4: Не используйте исключения для управления потоком

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

Правило 5: Сохраняйте первоначальную причину исключения

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

Дальнейшее обсуждение

В этой статье мы обсудили два типа ошибок, возникающих в Rest API: бизнес- и системные ошибки. Мы использовали это, чтобы поговорить о том, как мы должны по-разному относиться к двум классификациям в нашем коде. А затем мы дали несколько рекомендаций о том, как исключения должны проходить через ваше приложение. В следующей части этой серии мы поговорим о том, как сообщить внешнему миру об ошибке программы.

Для дальнейшего чтения,