Поймать все 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)
})
`