Catch all uncaughtException для приложения Node js

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

Ответ 1

Вы можете использовать процесс " 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);
  });

Ответ 2

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 3

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

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)
})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)
})

'