Поймать все uncaughtException для приложения Node js

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

3 ответа

Вы можете использовать процесс uncaughtException' а также 'unhandledRejection' События.

Также помните, что не безопасно возобновить нормальную работу после 'uncaughtException', потому что система становится поврежденной:

Правильное использованиеuncaughtException'должен выполнить синхронную очистку выделенных ресурсов (например, файловых дескрипторов, дескрипторов и т. д.) перед завершением процесса.

Пример:

process
  .on('unhandledRejection', (reason, p) => {
    console.error(reason, 'Unhandled Rejection at Promise', p);
  })
  .on('uncaughtException', err => {
    console.error(err, 'Uncaught Exception thrown');
    process.exit(1);
  });

Вы можете использовать API Домена: https://nodejs.org/api/domain.html Но это устарело и не рекомендуется в любом случае.

В общем, вы хотите обрабатывать ошибки везде, где они могут возникнуть, и избегать подхода "поймать все".

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

Вместо этого, лучший способ справиться с этим - это иметь сбой вашей программы, записать сбой (и дамп стека / ядра), а затем автоматически перезапустить его, используя pm2 или nodemon.

Для (очень) длинной, но проницательной речи Джойента (создателей Node) я настоятельно рекомендую вам прочитать эту ссылку: Обработка ошибок в Node.JS

Там также есть process.on('uncaughtException') событие (которое вы также не должны использовать)

Изменить: немного больше деталей и попытка решения вашей проблемы. Используя программное обеспечение, такое как pm2, для перезапуска приложения в случае сбоя, вы также сможете увидеть error.log, который даст вам трассировку стека. Таким образом, кажется, что единственное, что вам все еще нужно, это быть предупрежденным о сбое.

Для этого, возможно, вы захотите взглянуть на интерфейсы, такие как keymetrics (те же самые ребята, которые сделали pm2), которые потенциально могут предупредить вас об ошибках.

Классное решение, которое я использовал однажды, давным-давно, было следующим:

  • когда ваше приложение (пере) запускается, оно ищет журнал ошибок
  • Если он найдет один, он предупредит вас с содержанием файла журнала
  • затем переименовывает / перемещает файл журнала ошибок в другое место

Я бы не стал рекомендовать это решение, но оно соответствует всем нужным вам характеристикам, так что получайте удовольствие!

Edit2: Если вы хотите углубиться в темы разработки сервисов и лучших практик, взгляните на его ссылку, предложенную @Paul в комментариях: https://12factor.net/

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

var cluster = require('cluster');

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (var i = 0; i < numCPUs; ++i) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
    cluster.fork();
  });
} else {
  var http = require('http');
  var httpServer = http.createServer(app).listen(httpPort, function () {
      console.log('process id local', process.pid)
      console.log("http server started at port " + httpPort);
  });
}

process.on('uncaughtException', function (err) {
  console.error((new Date).toUTCString() + ' uncaughtException:', err.message)
  console.error(err.stack)
  process.exit(1)
})

`

Другие вопросы по тегам