В этой статье мы расскажем, какие типы ошибок возникают в Rest API, как мы можем перевести их на языки программирования, а также некоторые общие рекомендации по использованию исключений.
Классификация ошибок
Давайте начнем разговор с описания классификаций ошибок, с которыми обычно сталкиваются API:
- Бизнес-ошибки — ошибки, вызванные ожидаемыми случаями.
- Системные ошибки — ошибки, вызванные непредвиденными случаями.
Бизнес-ошибки возникают, когда программа не может продолжить выполнение из-за ожидаемого состояния ошибки. Это могут быть ошибки проверки или какой-либо другой случай, когда бизнес-логика указывает, что поток не может продолжаться.
Системные ошибки вызваны проблемами, связанными с непредвиденными случаями в коде. Это может быть вызвано непредвиденными ошибками или непредвиденным состоянием системы.
Для нас важно уметь различать два типа ошибок, поскольку это дает нам основу для дальнейших дискуссий.
Исключения
Теперь, когда у нас есть классификации ошибок, мы можем приступить к их переводу на язык программирования. Многие языки сообщают об ошибках с помощью исключений. Давайте посмотрим, как мы можем сопоставить эти ошибки с исключениями.
Когда мы работаем с ошибками, которые, как мы знаем, произойдут (т. е. когда мы выбрасываем исключение), мы должны разрешать выбрасывать базу BusinessException
. Есть несколько примеров того, как получить больше детализации, например, расширение этого исключения для пользовательских исключений или расширение базового класса Exception
для включения «кодов ошибок». Лично я бы предпочел расширить класс Exception
, включив в него код ошибки, потому что он переходит в удобочитаемые ответы при возврате их вызывающей стороне.
Вы можете включить другие исключения по умолчанию в ту же категорию, что и BusinessException
. Например, NullArgumentException
— это распространенный тип ошибки, когда вам имеет смысл продолжать его использовать. Я бы посоветовал свести количество таких исключений к минимуму, потому что поддержка большого количества исключений может быть обременительной, и это не имеет большого значения, когда речь идет о Rest API.
Все остальные исключения относятся к случаю системной ошибки. Это может быть DbException
, ConcurrentException
или любое другое необработанное исключение. Эти типы исключений могут попасть в вызывающую структуру без обработки. Это не означает, что с ними можно обращаться и/или преобразовывать в BusinessExceptions
.
Когда использовать исключения
Знание того, когда генерировать исключение, является широко обсуждаемой темой среди разработчиков. Моя позиция заключается в том, что вы должны попытаться использовать другие языковые конструкции для описания ситуаций, прежде чем полагаться на исключения. Использование исключений должно быть последним средством, когда есть реальная ошибка, и программа не может продолжаться, или вам нужно передать больше информации вызывающей стороне, чем предоставляет определение метода.
Например, один из наиболее распространенных случаев, когда исключение не следует использовать, — это когда вызывающая сторона запрашивает несуществующую запись БД. Мы можем вернуть либо null, либо необязательное значение в качестве результата вместо того, чтобы выдавать ошибку.
Это не четкое правило, и вы должны оценить свои варианты использования для наилучшего подхода. Например, если вы ожидали создания записи в БД, а этого не произошло, это будет исключением.
Распространение ошибок
Поняв, какие типы исключений может обрабатывать API, давайте поговорим о том, как справляться с этими исключениями.
Правило 1: Не перехватывайте исключения, которые вы не обрабатываете.
Это также известно как «проглатывание исключений». Это означает, что вы перехватываете исключение и ничего с ним не делаете. Пусть исключение всплывает до тех пор, пока его можно будет обработать или оно должно выйти за пределы службы во внешнюю систему.
Правило 2: Не делайте исключение из журнала и не перебрасывайте.
Честно говоря, это всего лишь Правило 1, но оно настолько серьезное, что требует отдельного правила. Пусть обработчик занимается регистрацией соответствующего сообщения.
Правило 3: поймать самое конкретное возможное исключение
Когда вы решите поймать исключение, поймайте наиболее конкретное возможное исключение. Это уменьшит вероятность того, что вы можете обработать неправильное исключение.
Правило 4: Не используйте исключения для управления потоком
Исключения не должны использоваться для управления потоком вашей программы. Это связано с тем, что обычно языки не оптимизируются для этого типа ветвления, и есть некоторая потеря производительности при компиляции информации, необходимой для создания исключения.
Правило 5: Сохраняйте первоначальную причину исключения
Может быть случай, когда вы хотите преобразовать исключение в другое. Вы всегда должны сохранять исходное исключение, чтобы у вас была точка отсчета того, где было создано исключение.
Дальнейшее обсуждение
В этой статье мы обсудили два типа ошибок, возникающих в Rest API: бизнес- и системные ошибки. Мы использовали это, чтобы поговорить о том, как мы должны по-разному относиться к двум классификациям в нашем коде. А затем мы дали несколько рекомендаций о том, как исключения должны проходить через ваше приложение. В следующей части этой серии мы поговорим о том, как сообщить внешнему миру об ошибке программы.
Для дальнейшего чтения,