Эй, подожди, что за несчастный путь? Хорошо, давайте начнем с самого начала, успешный путь — это сценарий по умолчанию, в котором нет исключительных или ошибочных условий, поэтому неудачный путь — это все остальные сценарии, в которых случаются исключительные ситуации или ошибки.
В этой статье мы попытаемся объединить несколько концепций, таких как «Любой» и «Проверено», в приложение REST.
- Моделирование несчастливого пути (исключения/ошибки)
- Обработка ошибок и сопоставление с кодами состояния HTTP
Предпосылки
- Базовое понимание DataTypes, Kotlin и SpringBoot
Моделирование несчастливого пути
«Как пользователь, я хочу получать бронирования данного продукта по идентификатору»
У нас есть счастливый путь, на котором мы можем ответить на запрос пользователя бронированием (зеленые стрелки), и есть 5 путей, на которых мы должны вернуть сообщение об ошибке, в котором говорится, что мы не можем вернуть то, что они просили.
Эти ошибки — это то, что в Java мы привыкли «моделировать» как исключения. Программист должен иметь детализированные исключения, описывающие каждый тип ошибки, как мы все делали в начале, вы начинаете генерировать new RuntimeException(), который ни хрена не говорит об ошибке ( несчастливый путь), и когда это происходит в производстве, вам просто нужно отладить свой код, чтобы узнать, что произошло. После нескольких ударов по лицу вы начинаете (надеюсь :) ) создавать пользовательские исключения и включать описания, позволяющие с первого взгляда узнать о контексте сбоя. На данный момент вы в порядке (с точки зрения Java).
Но у исключений есть несколько недостатков, исключение может быть просто потеряно, и если документация недостаточно хороша, вы обнаружите некоторые из них во время выполнения ›.‹
Здесь мы можем пойти дальше и использовать типы данных и соглашения для улучшения этого сценария.
Типы данных на помощь: любой и проверенный
Тип данных — это абстракция, которая инкапсулирует повторно используемый шаблон кодирования. Эти решения имеют каноническую реализацию, обобщенную для всех возможных применений.
Предложение состоит в том, что если мы моделируем наш сценарий успеха, то же самое делаем и для неудач. Как тогда мы сообщаем об ошибке? Делая это явным в типе данных, который мы возвращаем.
Либо используется для сокращения вычислений при первой ошибке, что соответствует логическому ИЛИ или + как алгебраическому типу данных. Мне нравится думать, что это коробка с двумя сегментами: по соглашению левый сегмент используется для сохранения неудачи, а правый сегмент — для успеха. Здесь вы можете найти действительно хорошую документацию по этому типу данных.
Существует много документации с множеством небольших примеров, мы переходим непосредственно к реальному варианту использования. В нашем примере мы должны использовать внешний сервис и десериализовать его содержимое в нашу модель Booking. Сервис возвращает список бронирований даже при поиске по ID.
Проверьте, что мы сделали, сигнатура нашего метода fun get(pnr: String): Либо‹BookingRetrievalError, Booking›говорит, что он вернет Booking (справа), когда все идет вправо и BookingRetrievalError (слева) в случае сбоя. Класс BookingRetrievalError моделирует все возможные сбои, поэтому вы можете обрабатывать каждый из них, избегая неожиданностей во время выполнения.
- BookingNotFound -› бронирование с указанным pnr (id) не найдено
- SupplierFailure -› внешнему поставщику не удалось обработать наш запрос
- UnexpectedFailure -› мы не знали, что случилось
Как видите, неожиданностей во время выполнения не будет, все возможные сбои есть во время компиляции.
Теперь у нас есть вызов внешней службы, предположим, что нам нужно управлять только бронированиями со статусом Подтверждено и с некоторой ценностью для агентства. Мы также хотим смоделировать наши валидации, чтобы было ясно как вода, почему наш сервис может дать сбой.
Сколько раз вы заполняли форму, а затем отправляли. Выскакивает ошибка о том, что имя пользователя уже занято, вы меняете его, а затем отправляете повторно. Появляется еще одна ошибка, говорящая о том, что ваш адрес не имеет ожидаемого формата. Напрасно поминаете Господа и удивляетесь, почему сразу все ошибки валидации сходятся... Вот и тип данных Validated.
Мы перечисляем наши ошибки, как мы это делали в нашем репозитории, чтобы охватить все возможные пути, как мы это делали раньше.
Здесь — это остальная часть примера, охватывающая сквозную службу REST, довольно близкую к продуктивному приложению. Вы можете запустить его и играть с ним. В этой статье есть примеры для каждой неудачи.
Моделирование неудовлетворительного пути — это шаг вперед к созданию надежных, отказоустойчивых и простых в мониторинге приложений. Тесты легко писать, и их гораздо легче охватить кодом. Никаких сюрпризов в 3 часа ночи :)
Удачного кодирования!
Что дальше?
Глава 19. Обработка ошибок
Когда мы говорим о «чистой обработке ошибок, мы имеем в виду алгоритмы, которые не требуют ничего из монады IO…book .realworldhaskell.org»
Железнодорожное программирование
Эта страница содержит ссылки на слайды и код из моего выступления «Железнодорожное программирование. Вот аннотация для…fsharpforfunandprofit.com»