Поймаются ли исключения в лямбдах в javascript / node.js? - PullRequest
8 голосов
/ 23 февраля 2011

У меня есть сервер node.js, который я хочу обрабатывать исключения без сбоев, и у меня есть код, подобный приведенному ниже.Что я хочу знать, со всеми событиями, вызываемыми событиями, обратными вызовами, лямбдами и прочим, будут ли мои исключения по-прежнему обнаруживаться моей главной точкой входа?

try {

  http.get(..., function(results) {
    // Might get an exception here
    results.on('data', function () {
      // Might also get an exception here
    });
    results.on('end', function () {
      // Might also get an exception here
    });
  });

} catch(e) {
  // Will the exceptions from the lambdas be caught here?
  console.log('Nicely caught error: (' + e.name + '): ' + e.message);
}

Спасибо

Ответы [ 3 ]

8 голосов
/ 23 февраля 2011

Это зависит от потока управления. Node.js делает акцент на том, что он асинхронный, и один из главных недостатков асинхронности заключается в том, что код не работает так, как вы могли бы привыкнуть к синхронизированному языку.

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

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

try/catch блоки работают со стеком вызовов. То есть, когда выдается исключение, среда выполнения раскручивает стек вызовов, пока не найдет блок catch, который окружает вызов, вызвавший исключение. Но, поскольку http.get является неблокирующим вызовом, он завершается сразу после регистрации некоторых обратных вызовов, и обработка продолжается. Обратные вызовы вызываются в отдельном «потоке», и поэтому вызовы не вложены в исходный блок try/catch.

Диаграмма действительно помогла бы объяснить здесь, но, к сожалению, у меня ее нет.

2 голосов
/ 01 марта 2011

В вашем примере кода ни одно из потенциальных исключений, вызванных в обратном вызове http.get, не попадет в ваш блок catch. Стек обратного вызова строится из цикла событий узла, когда данные доступны для чтения.

Есть способ перехватить необработанные исключения в узле:

process.on("uncaughtException", function (err) {
    console.log("uncaught exception: " + err);
});

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

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

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

2 голосов
/ 23 февраля 2011

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

Бросок поднялся бы по цепочке вызывающих, которая обычно не знает, что делают обратные вызовы (например, уровень tcp не делаетвсе равно, что его данные анализируются как http).Выбрасываемые исключения плохо подходят для асинхронного программирования.

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