Как стать автором
Обновить

Ошибки, RxJS & Angular

Angular *

Что привлекает в Ангуляре экспертов и удручает начинающих? Одно и тоже, RxJS.

   Почему же это так сложно для начинающих? Одна из причин - есть огромное количество операторов, которые нужно просто знать, и без поиска понимать в чем разница между concatMap, switchMap и mergeMap. Почему же это так нравится тем, кто это уже изучил? Потому что вы начинаете понимать все могуществао RxJS, когда парой операторов вы можете сделать то, что в императивном коде писали бы полдня на двух страницах. Ведь это так приятно, ощущать себя богом, когда код просто отскакивает от ваших пальцев, а вы радостно рассказываете коллегам как вы классно и главное просто решили задачу.

  Вместе с тем каждый помнит, что вызывать множественные subscribe плохо (как и вообще подписываться), вызывать сайд эффекты из tap (хотя конечно все так делают). А что же чаще всего забывают с RxJS? Ошибки. Какие ошибки? Лично я выделяю всего два типа ожидаемые и неожиданные.

Неожиданные ошибки - это те ошибки, которые возникают в результате плохого кода либо неожиданного JSON-ответа сервера - деление на ноль, обращение к null-объекту, некорректный парсинг JSON. Можно привести много примеров, главное то, что это полноценные ошибки, которые требуют изменений в вашем коде.

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

Такие типы ошибок, я считаю, надо разделять и в последствиях - в случае первых красиво падать, в случае вторых - уметь с ними работать и показывать нашим пользователям что-то, из чего можно сделать красивый скриншот “виноваты они а не мы”. Как это сделать? Используя такое представление данных, которое само по себе покажет вам, что в нем могут быть как данные, так и ошибка. Встречайте,

В общем случае это union тип, слева - ошибка, справа - правильные данные.

Впрочем, самописный тип я предлагаю не использовать, а взять готовый. Многие берут тип из библиотеки fp-ts, я же предлагаю взять более легковесный и понятный @sweet-monads/either.

Давайте создадим простое Ангуляр-приложение, которое будет грузить данные пользователя github, а потом (не)красиво падать при попытке загрузки несуществующего по нажатию кнопок.

StackBlitz Demo

Код, соответственно, выглядит вот так

Это довольно простое приложение, падающее при попытке сделать что-то, о чем мы не подумали (в данном случае - загрузить несуществующего пользователя). Печально, но визуально это будет выглядеть в лучшем случае как неработающая кнопка, в худшем - все, что было основано на таком коде, также упадет.

Попыток решения ошибок способами RxJS много, предлагаю изучить в прекрасной статье RxJs Error Handling: Complete Practical Guide

В Ангуляре я чаще всего видел решение через определение в модели компонента отдельных полей data и error.

Почему это (а также другие способы решения) плохо предлагаю посмотреть в прекрасном ролике от Артём Кобзаря и Дмитрия Махнёва (не|ну)жная монада Either на практике и в теории

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

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

В чём прелесть такого оператора как отдельной единицы в в приложении - то что мы можем его применять точечно, в отдельных местах приложения, а не мигрировать целиком.

Код с использованием этого оператора будет выглядеть вот так

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

 Основные изменения - появление компонента Either и использование правых данных через структурную директиву ifRight.

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

Заключение

Как видите, здесь мы уверены что ошибка будет обработана более то в будущем если нам понадобится мы всегда сможем например залогировать как с помощью операторов mapEither, switchMapEither (есть в примере)

Теги:
Хабы:
Рейтинг 0
Просмотры 184
Комментарии 0
Комментарии Комментировать

Истории

Работа