8

Лучшие практики обработки исключений в Node.js

7

Я только что начал тестировать node.js несколько дней назад и заметил, что Node завершает работу каждый раз, когда в моей программе возникает необработанное исключение. Это отличается от обычного серверного контейнера, с которым я знаком, где только рабочий поток завершает свою работу при возникновении необработанных исключений, а контейнер все еще может принимать запросы. У меня возникло несколько вопросов:

  • Является ли process.on('uncaughtException') единственным эффективным способом защиты от этого?
  • Поймает ли process.on('uncaughtException') необработанные исключения во время выполнения асинхронных процессов?
  • Существует ли модуль, который уже реализован (например, отправка электронной почты или запись в файл), который я мог бы использовать в случае необработанных исключений?

Я был бы признателен за любые указания или статьи, которые бы показали мне общепринятые лучшие практики для обработки необработанных исключений в node.js.

4 ответ(ов)

0

Вы можете перехватывать необработанные исключения, но это имеет ограниченное применение. Дополнительную информацию можно найти по ссылке: http://debuggable.com/posts/node-js-dealing-with-uncaught-exceptions:4c933d54-1428-443c-928d-4e1ecbdd56cb.

Для перезапуска процесса Node.js в случае его сбоя вы можете использовать такие инструменты, как monit, forever или upstart. Лучшее, на что вы можете надеяться, — это корректное завершение работы приложения (например, сохранить все данные в памяти в обработчике необработанных исключений).

0

Один из случаев, когда использование конструкции try-catch может быть оправдано, - это в цикле forEach. Хотя этот цикл синхронный, вы не можете просто использовать оператор return в внутренней области видимости. Вместо этого можно применить подход с try и catch, чтобы возвратить объект ошибки в соответствующей области видимости. Рассмотрим следующий пример:

function processArray() {
    try { 
       [1, 2, 3].forEach(function() { throw new Error('exception'); }); 
    } catch (e) { 
       return e; 
    }
}

Это комбинация подходов, описанных выше @balupton.

0

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

Bunyan — популярный фреймворк для логирования в Node.js. Он поддерживает запись в разные выходные места, что делает его полезным для локальной отладки, если избегать использования console.log.

В обработчике ошибок вашего приложения вы можете записать ошибку в файл журнала.

var log = bunyan.createLogger({
  name: 'myapp',
  streams: [
    {
      level: 'error',
      path: '/var/tmp/myapp-error.log'  // логировать ошибки в этот файл
    }
  ]
});

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

Если вы решите использовать Raygun, его довольно легко настроить:

var raygunClient = new raygun.Client().init({ apiKey: 'ваш API ключ' });
raygunClient.send(theError);

В связке с инструментами вроде PM2 или forever ваше приложение сможет аварийно завершиться, зафиксировать, что произошло, и перезапуститься без особых проблем.

0

Использование доменов для обработки исключений на уровне API или функции может быть интересным подходом, особенно если вы хотите упростить код обработки исключений в каждой асинхронной функции. Однако следует учесть несколько моментов.

Во-первых, действительно, при использовании новых доменов для каждой функции overhead может быть минимальным, и в некоторых случаях производительность может быть даже лучше, чем при использовании конструкции try-catch. Это связано с тем, что домены способны захватывать исключения, возникающие в асинхронных вызовах, без необходимости оборачивать каждую часть кода в try-catch.

Тем не менее, использование доменов в Node.js считается устаревшим и может быть не самым лучшим выбором. В последних версиях Node.js рекомендуется использовать конструкции async/await вместе с try-catch для обработки исключений, так как это более современный и понятный способ управления ошибками. Кроме того, домены могут привести к путанице в управлении контекстом и сложности отладки.

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь