Node.js - домен для экспресс-запроса внутри другого домена

Обработка ошибок в Node. Ах!

Я пытаюсь создать такое базовое приложение Node ...

Кластер -> Рабочий -> Домен сервера -> Домен экспресс-запроса

Таким образом, если ошибка возникает на 18 уровнях в стеке вызовов из-за того, что кто-то неправильно написал свое имя в форме входа в систему, весь сервер не выйдет из строя.

Вот базовый код для имитации рабочей части:

var domain, server;

domain = require('domain');
server = domain.create();

server.on('error', function(e) {
    console.log('total meltdown...', e.stack);
});

server.run(function() {

    var express = require('express')();

    express.configure(function() {

        // Domain on EVERY request
        express.use(function(req, res, next) {
            var d = domain.create();

            d.on('error', function(e) {
                console.log('fired REQUEST error', e.stack);
                next(e);
            });

            d.run(next);

        });

        // Generic error handler
        express.use(function(e, req, res, next) {
            res.status(500);
            res.end('oops');
        });

        // Serve the request with a blatent error
        express.get('/', function(req, res) {

            this_function_does_not_exist();
            res.end('we will never get here');

        });
    });

    // Fire 'er up
    express.listen(3000);
});

Чего я жду ...

Я скручиваю http://localhost:3000/, получаю небольшую милую ошибку «упс» и вижу в консоли «активированную ошибку REQUEST» и стек ошибок.

Что на самом деле происходит ...

Я получаю это как в ответе браузера, так и в консоли ...

ReferenceError: this_function_does_not_exist не определен в /Stuff/test.js:38:13 в обратных вызовах (/Stuff/node_modules/express/lib/router/index.js:161:37) в параметре (/ Stuff / node_modules / express / lib /router/index.js:135:11) на проходе (/Stuff/node_modules/express/lib/router/index.js:142:5) в Router._dispatch (/ Stuff / node_modules / express / lib / router / index .js: 170: 5) в Object.router (/Stuff/node_modules/express/lib/router/index.js:33:10) в следующем (/Stuff/node_modules/express/node_modules/connect/lib/proto.js : 190: 15) в следующем (/Stuff/node_modules/express/node_modules/connect/lib/proto.js:192:9) в b (domain.js: 183: 18) в Domain.run (domain.js: 123 : 23)

Так почему бы ему пойти и сделать что-то подобное?


person Lee Benson    schedule 18.07.2013    source источник


Ответы (1)


Хорошо, решено - в Express есть блок try / catch, который сначала обращается к моему несуществующему вызову функции.

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

        process.nextTick(function() {
            this_function_does_not_exist();
            res.end('we will never get here');
        });

ТОГДА домен захватит его.

person Lee Benson    schedule 21.07.2013
comment
я ценю, что вы указали почему - но вы на самом деле не даете образец кода, который показывает, как его нужно вынуть из текущего стека вызовов - person Tom Carchrae; 16.10.2013
comment
если он является частью текущего стека вызовов, Express его поймает, и он не будет «пузыриться» до обработчика домена. Проблема в том, что мы не всегда знаем, когда это произойдет, и это может быть вне функции, которая вызывает res.send () / отбрасывает что-либо обратно в браузер. Таким образом, используя process.nextTick, мы эффективно обходим стек Express и запускаем его независимо в конце текущего стека вызовов ... но все еще в контексте домена. Итак, возникает ошибка, домен забирает ее и возвращает обратно в res.send, который находится в контексте моего исходного кода примера. Это поможет? - person Lee Benson; 16.10.2013
comment
спасибо - я понимаю, что вы говорите. вы хотите вызвать исключение в nextTick (). - person Tom Carchrae; 17.10.2013