Программа Node.js завершается, даже если обрабатываются необработанные исключения - PullRequest
1 голос
/ 27 июня 2019

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

process.on("uncaughtException", err => {
    console.log('Handling exception');
});

console.log('starting...');

function f() {
    throw(new Error('Error'));
}

f();
console.log('Done');

Когда язапустив код, я получил следующий вывод:

starting...
Handling exception

По какой-то причине, хотя исключение было обработано, программа вышла без выполнения последней строки кода.Когда я завернул вызов на f() блоком try-catch, на экране была выполнена последняя строка и слово «Done» было напечатано.

Мои вопросы:

  1. Это ожидаемое поведение?
  2. Почему существует разница между этими двумя механизмами (прослушивание события и использование try-catch)?

1 Ответ

1 голос
/ 27 июня 2019

Это именно то поведение, которое вы ожидаете, неперехваченное исключение остановит нормальное выполнение скрипта, поэтому никогда не будет выполнен вызов журнала «Done».

Вы можете увидеть еще лучший пример этого в документации по Node.js здесь: https://nodejs.org/api/process.html#process_event_uncaughtexception

Как сказано в документации:

Note that 'uncaughtException' is a crude mechanism for exception handling intended to be used only as a last resort.

Они явно регистрируются "Это не будет работать ", поскольку это ожидаемое поведение.

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

process.on('uncaughtException', (err, origin) => {
  fs.writeSync(
    process.stderr.fd,
    `Caught exception: ${err}\n` +
    `Exception origin: ${origin}`
  );
});

setTimeout(() => {
  console.log('This will still run.');
}, 500);

// Intentionally cause an exception, but don't catch it.
nonexistentFunc();
console.log('This will not run.');

Обработчик uncaughtException предназначен именно для этого: перехватывать любые исключения, не обработанные обработчиками try ... catch, в вашем собственном коде.Основная цель должна заключаться в том, чтобы регистрировать ошибки, чтобы они могли быть исправлены позже.

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

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

Сценарий 1:

// Keep the script alive by setting a timeout. Because we have an exception handler in place we can keep doing stuff!
let interval = setInterval(() => console.log("I'm still alive!!"), 500);
setTimeout(() => { clearInterval(interval); console.log("Timeout done...")} , 5000);

process.on("uncaughtException", err => {
    console.log('Handling exception');
});

console.log('starting...');

function f() {
    throw(new Error('Error'));
}

f();

console.log('Done');

Сценарий 2:

// Keep the script alive by setting a timeout. Since there is no exception handler set the script will terminate immediately in any case.

let interval = setInterval(() => console.log("I'm still alive!!"), 500);
setTimeout(() => { clearInterval(interval); console.log("Timeout done...")} , 5000);

console.log('starting...');

function f() {
    throw(new Error('Error'));
}

f();

console.log('Done');

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...