Обработка ошибок

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

Например, если поток взаимодействует с внешней базой данных или API, что произойдет, если они перестанут отвечать на запросы?

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

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

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

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

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

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

Запись ошибок в журнал#

Когда узел регистрирует ошибку, она появляется на боковой панели отладки.

Ошибка на боковой панели отладки

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

Уловимые ошибки#

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

Использование узла Catch

Если ошибка поймана узлом Catch, она не будет выведена на боковой панели отладки.

Сообщение, отправленное узлом Catch, будет сообщением, которое предоставил узел, сообщивший об ошибке. Это сообщение также будет иметь свойство error, которое содержит информацию об ошибке:

{
"payload": ...,
"error": {
"message": "Ошибка",
"source": {
"id": "12345678.9abcde",
"type": "function",
"name": "Моя функция",
"count": 1
}
}
}

Свойства объекта msg.error:

  • message - текст сообщения об ошибке
  • source - информация об узле, зарегистрировавшем ошибку:
    • id - идентификатор узла
    • type - тип узла
    • name - имя узла, если установлено
    • count - сколько раз данное сообщение об ошибке было брошено этим узлом. Это свойство используется средой выполнения для обнаружения сообщений, застрявших в цикле - когда они передаются обратно на узел источника ошибки, который затем снова регистрирует ошибку и т.д. Среда выполнения позволит сообщению повторить цикл 9 раз, прежде чем зарегистрировать другую, неуловимую ошибку, чтобы разорвать замкнутый цикл. Удаление этого свойства в сообщении отключит проверку зацикленности.

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

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

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

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

Ошибки в подпотоках#

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

Неуловимые ошибки#

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

Узел может предоставить альтернативные способы обработки ошибки. Например, обновлением своего статуса (который можно отслеживать с помощью узла Status). Или может отправлять сообщение как обычно, но с некоторыми дополнительными свойствами, указывающими на ошибку.

Ошибки uncaughtException#

Это особый тип ошибок Node.js (платформы, используемой Ботодромом), которые могут возникнуть, когда узлу не удалось должным образом обработать внутреннюю ошибку. Они вызывают завершение работы всей среды выполнения Ботодрома, поскольку это единственное безопасное действие.

Это может показаться чрезмерным, но, цитируя документацию Node.js:

Попытка возобновить работу в обычном режиме после неперехваченного исключения (uncaughtException) может быть аналогична выдергиванию шнура питания при обновлении компьютера. В девяти случаях из десяти ничего не происходит. Но в десятый раз система оказывается поврежденной.

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

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

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

Если ошибка была вызвана узлом Ботодрома, а не вашим кодом в узле Function, сообщите нам об этом.

Обработка изменений статуса#

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

Так же, как узел Catch может использоваться для обработки событий ошибок, узел Status можно использовать для обработки изменений в статусе узла.

Сообщение, отправленное узлом Status, включает свойство status, которое предоставляет информацию о статусе и узле, вызвавшем событие.