Как стать автором
Обновить

Пуленепробиваемый Node.js

Время на прочтение2 мин
Количество просмотров27K
Проблемы индейцев
Одним из остававшихся до недавнего времени недостатком Node.js, который отпугивал бекенд-разработчиков от использования Node.js, был тот факт, что непойманное исключение в потоке рушило воркера, и все клиенты, которые ждали от него ответа, не получали ничего.

tl;dr Eсть новое API для асинхронного try\catch. Из статьи можно скопипастить пример и поиграться.

Рассмотрим ситуацию:
У нас есть запрос к веб серверу ноды, в процессе обработки данных, полученных из базе данных происходит какая-то проблема (неверные параметры, которые нельзя валидировать, отвалилась стойка с базой данных, или просто невнимательность) — возникает ошибка. До начала нашего запроса было 5 запросов от других клиентов и у них начала грузиться страница. После запроса поступало еще 10 запросов от других пользователей. И вот она ошибка, в недрах коллбеков одного из параллельно выполняющихся запросов. Отваливаются все 16 запросов. Страдают невинные.

Можно было бы создавать на каждый запрос отдельного воркера, но это очень накладно по ресурсам.
Можно оберунть опасный кусок в try\catch, но на сложных системах это просто невозможно.
Можно на свой страх и риск надеяться, что все будет верно, а потери будут невелики.

Не канонично.

Да приидет Domain
Итак, в версии 0.8 появилась серебряная пуля, мастер отлова ошибок, непревзойденный Domain. На данный момент API находиться в статусе unstable, но уже им можно пользоваться.

Простой пример:
var domain = require('domain'),
    server = require('http').createServer(function(req, res) {
        
        // Создаем домен
        var d = domain.create();

        // Вешаем обработчик ошибки, который вернет 500й статус и текст проблемы
        d.on('error', function(err) {
            console.error('error', err.stack);
            res.statusCode = 500;
            res.setHeader('content-type', 'text/plain');
            res.end('Houston, we have a problem!\n');
        });

        // Добавляем наши переменные, которые тоже могут сгенерировать ошибки самостоятельно
        d.add(req);
        d.add(res);
        
        // Запускаем потенциально опасный код внутри домена
        d.run(function () {
          switch(req.url) {
          case '/error':
              setTimeout(function() {
                   // Вызываем ошибку - несуществующий метод необъявленной переменной
                   uncaught.error();
              });
              break;
          default:
              res.end('ok');
          }
        });
   });
server.listen(8080);



Запустив этот простой скрипт, при переходе на корневой адрес у нас все ОК, а вот если перейти по адресу /error, вы увидите в консоли лог ошибки, а в браузере — корректное сообщение, что что-то пошло не так, и статус 500.

P.S. Простите за орфографию и пунктуцию, буду рад указанию на ошибки.
Теги:
Хабы:
Всего голосов 56: ↑47 и ↓9+38
Комментарии21

Публикации

Истории

Работа

Ближайшие события