Рубрики
Uncategorized

Управление ошибками в приложениях node.js

Эта статья была первоначально опубликована в управлении ошибками в … Tagged с узлом, JavaScript, DevOps, Microservices.

Микросервисы с node.js (серия 2 частей)

Эта статья была первоначально опубликована в

Управление ошибками в приложениях node.js | Deepal Jayasekara | Блог Дипала

Deepal Jayasekara ・ 2 января 2020 г. ・ blog.insiderattack.net

Это вторая статья серии, посвященной созданию архитектуры микросервиса с Nodejs. Вы можете получить доступ к остальным статьям в серии ниже:

  • Bunyan json вводится с Fluentd и Graylog
  • Управление ошибками в приложениях node.js (эта статья)
  • Реализация источника событий и рисунка CQRS с MongoDB
  • Конечные точки проверки Canary Check (скоро наступит)
  • Написание миграции базы данных MongoDB с помощью node.js (скоро)

«Управление ошибками» — это странное название. Но я имел в виду это. Обработка ошибок — это общая тема, о которой все говорят и пишет. Обработка ошибок в Nodejs? Вы найдете множество статей, написанных об обработке ошибок в Nodejs. Есть причина для этого. Большинство разработчиков, которые являются новичками в асинхронном программировании в node.js, часто путают, как правильно обрабатывать различные типы ошибок. Попробуйте … Catch не всегда входит в спасение, если вы находитесь в асинхронном программировании. Я также перечислил некоторые из лучших практик обработки синхронных и асинхронных ошибок в node.js в одной из моих предыдущих статей об разработке приложений Secure Node.js. И наступает «но».

Предполагая, что вы правильно обработали ошибки приложения, и вы успешно поймали ошибку. Следующая самая важная часть — это то, что делать с ошибкой, которую вы только что поймали. Просто зарегистрируйте его и проглотите, как будто ничего не случилось? Стоит ли обострить ошибку? А где это должно быть в конечном итоге? Если ваше приложение поймало ошибку при обработке HTTP -запроса, отправленного одним из потребителей вашего API, следует ли жаловаться на ошибку потребителю? Если да, то как? Есть тысячи вопросов. В этой статье я собираюсь обсудить некоторые ошибки, которые я совершал, и я видел, прежде чем придумать правильный способ решения большинства этих проблем. Следовательно, Имя «Управление ошибками»

Чего нам нужно достичь?

В целях нашего руководства давайте представим, что наше приложение является микросервисом, основанным на Nodejs, который разоблачает API REST и разговаривает с одной или несколькими сторонними услугами через сеть. Итак, чего нам на самом деле нужно достичь?

Нам нужно правильно обработать ошибки нашего приложения, чтобы:

  • Результат каждой возможной ошибки должен быть предсказуемым
  • Приложение может восстановиться после критических ошибок без ручного вмешательства.
  • Ошибки при обработке HTTP -запроса передаются клиенту вместе с «минимальной необходимой, но описательной информацией», которая поможет клиенту предпринять действия на основе этого.
  • Корская причина ошибки должна быть легко прослеживаемой и отладкой.

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

1. Неправильно обрабатывая асинхронные ошибки

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

  • Используя обещания и обещание обратные вызовы — используйте .catch для обработки
  • Используя Асинк-ават для разрешения обещаний (или с использованием генераторов ES6 с

Тем не менее, есть немного запутанный сценарий при использовании ждет Анкет Смотрите следующие два примера. Эти примеры показывают тело асинхронной функции, написанной двумя разными способами. Но поймать Блок в примере 2 бесполезен, потому что обещание, возвращаемое myasyncfunction () Просто вернулся к вызывающему абоненту вместо того, чтобы ждать, пока он не будет решена/отклонен. Следовательно, любые отзывы обещания должны быть обработаны в сфере абонента.

2. Неправильно обрабатывать не учитывая

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

Uncaughtexception и Unkendledrection это два сценария, где приложение не должно продолжаться. Если вы явно добавляете слушателей к этим двум событиям, вам нужно убедиться:

  • Войдите достаточно информации об ошибке (возможно, отправьте их в систему управления журналами или APM -сервер), чтобы ее можно было исследовать позже.
  • Заставьте выйти из приложения, чтобы ваш менеджер процессов/оркестратор Docker запустил процесс замены.

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

Плохой:

Хорошо:

3. Маскирующие ошибки

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

Плохой:

Хорошо:

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

5. Не преобразование общих ошибок в конкретные ошибки

Преобразование общих объектов ошибки в конкретные объекты ошибки важны, если вашему приложению нужно принимать разные решения на основе типа ошибки. Пример использования применения таких конкретных ошибок выглядит следующим образом:

JavaScript Ошибка Объект очень общий. Чтобы определить специфику ошибки, вам нужно проверить error.message , error.code , error.stack характеристики. Это не удобный способ, если вы планируете масштабировать свое приложение. Есть несколько конкретные ошибки брошен Node.js, такой как TypeError , Синтаксисеррок , DrangeError , и т.д. Но они не так используются для других целей.

Здесь вам нужно определить свои собственные типы ошибок и бросить правильную ошибку в нужное время. Это делает ваши ошибки приложения более эксплуатационными и легко подлежат сбору. Давайте посмотрим пример.

Несмотря на то, что я нашел этот подход более надежным и простым в обращении. Таким образом, вам не нужно просить своих со-разработчиков придерживаться обычного списка кодов ошибок и проверить на наличие error.code Каждый раз, когда вы ловите ошибку, чтобы определить следующие шаги.

6. Маскировка неожиданных ответов от сторонних услуг

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

Смотрите следующую гипотетическую программу:

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

Что, если разработчики этого API изменяют структуру объекта ответа такой, что Body.users становится неопределенное ? Ваше приложение все равно будет продолжать работать с помощью значения по умолчанию [] не бросая подсказку о том, что происходит. К тому времени, когда вы определили, что что -то не так, может быть трудно оправиться.

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

7. Не используя соответствующий уровень журнала для ошибок

Выбор лучшей библиотеки журнала для вашего приложения недостаточно, если вы не используете ее должным образом. Одной из наиболее распространенных особенностей всех библиотек журналов является то, что вы можете регистрировать сообщения на разных уровнях журнала и, возможно, отправлять эти журналы каждого уровня в другой пункт назначения (например,, например, stdout , Syslog , Файл и т.д.). Чтобы сделать это правильно, вы должны выбрать правильный уровень журнала для вашего сообщения на основе того, насколько важно сообщение. Наиболее распространенные уровни журналов следующие:

  • log.debug — Все сообщения, которые не являются решающими, но могут быть важны, чтобы отлаживать что -то позже.
  • log.info -Все информативные сообщения, которые имеют решающее значение для определения успешного (или не облегающего) действия.
  • log.warn — Все предупреждения, которые не являются критическими и не требуют немедленных действий, но важны для расследования позже.
  • log.error — Все ошибки, которые требуют немедленного внимания, и могут привести к катастрофическому сценарию, если их игнорировать.
  • log.fatal — Все ошибки, которые указывают на отключение обслуживания или отказ критического компонента, который требует немедленного действия, чтобы восстановить.

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

PS: Проверьте мой пост о настройке схемы агрегации журнала с Bunyan Logger, Fluentd и Graylog:

Bunyan json вводится с Fluentd и Graylog | Deepal Jayasekara | Блог Дипала

Deepal Jayasekara ・ 2 января 2020 г. ・ blog.insiderattack.net

Вот и все. Это всего лишь несколько важных сохранений в отношении «управления ошибками» в приложениях node.js. Ваше мнение всегда приветствуется. Не стесняйтесь поставить комментарий. Спасибо.

Фоновое изображение предоставлено: https://images.axios.com/WVWPMo4kVq7ZSwcIr16u8QZ8nAY=/0x280:5100×3149/1920×1080/2018/06/01/1527894970857.jpg

Микросервисы с node.js (серия 2 частей)

Оригинал: «https://dev.to/deepal/error-management-in-node-js-applications-3d2k»