Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何在域错误处理程序内发送响应_Node.js_Http - Fatal编程技术网

Node.js 如何在域错误处理程序内发送响应

Node.js 如何在域错误处理程序内发送响应,node.js,http,Node.js,Http,我有类似的想法: var domain = require ("domain"); var http = require ("http"); var d = domain.create (); d.on ("error", function (error){ console.error (error); //res.writeHead (500) //res.end () }); d.run (function

我有类似的想法:

var domain = require ("domain");
var http = require ("http");

var d = domain.create ();
d.on ("error", function (error){
    console.error (error);
    //res.writeHead (500)
    //res.end ()
});
d.run (function (){
    http.createServer (function (req, res){
        null.error
    }).listen (1337, "localhost");
});
我的所有服务器都在域内运行。如果在请求期间发生错误,我想向用户发送500个错误,但在错误处理程序中,我无法访问响应对象


我的第一次尝试是为每个请求使用一个显式域,如文档所述:

var d = domain.create ();
d.on ("error", function (error){
    //res.writeHead (500);
    //res.end ()
    console.error (error);
});
d.run (function (){
    http.createServer (function (req, res){
        var dreq = domain.create ();
        dreq.add (req)
        dreq.add (res)
        dreq.on ("error", function (error){
            res.writeHead (500);
            res.end ()
            console.error (error);
        });
        null.error
    }).listen (1337, "localhost");
});
从不调用
dreq
错误处理程序,因为
req
res
从不发出错误,错误发生在执行时,它是一个类型错误


我的第二次尝试是使用闭包保存对
res
对象的引用,例如事件发射器:

var domain = require ("domain");
var http = require ("http");
var events = require ("events");

var emitter = new events.EventEmitter ();

var d = domain.create ();
d.on ("error", function (error){
    emitter.emit ("error", error);
});
d.run (function (){
    http.createServer (function (req, res){
        emitter.once ("error", function (error){
            res.writeHead (500);
            res.end ();
            console.error (error);
        });
        null.error
    }).listen (1337, "localhost");
});
这样,错误会在错误处理程序中捕获,然后发出,这样我就可以使用响应对象向用户发送消息。如果您对node.js的基础知识了解很少,那么您会发现这个解决方案完全有漏洞。如果事件循环中有5个用户请求,其中1个执行了抛出错误的任务,则发射器将执行所有错误处理程序,当只有1个用户收到500错误时,5个用户将收到500错误通知


我最后一次尝试是为每个请求创建子上下文。医生们对这种模式只字不提。这让我有点困惑:

为了防止内存过度使用,域对象本身不会隐式添加为活动域的子对象。如果是,那么就很容易阻止请求和响应对象被正确地垃圾收集

如果要将域对象嵌套为父域的子对象,则必须显式添加它们,然后在以后处置它们

我是在引入内存泄漏吗


简单的解决方案是为每个请求分配一个唯一的ID,并将它们保存在一个对象或数组中,当发射器发出时,找到必须在给定唯一ID的情况下执行的处理程序。完全不可接受



如果我无法保存对
res
对象的引用,我如何在域错误处理程序中向用户发送错误?

您上次发布的解决方案实际上是您应该做的。这与文档建议的嵌套类型不同。您所做的只是在域中包装潜在的(或者,在本例中,肯定是)错误代码,以便在发生错误时由域处理。

此解决方案对我来说很好:

var http = require('http');
var domain = require('domain');

var server = http.createServer (function (req, res) {
    var reqDomain = domain.create();
    reqDomain.on('error', function (error) {
        res.writeHead(500);
        res.end('error 500');
        console.error(error);
    });
    res.on('close', function () {
        reqDomain.dispose();
    });
    reqDomain.run(function () {
        // Request handler code here
        null.error
    });
}).listen(3000);

server.on('error', function (error) {
    console.error('Server error: ' + error);
});

此解决方案是赢家:

var domain = require ("domain");
var http = require ("http");

var d = domain.create ();
d.on ("error", function (error){
    console.error (error);
});
d.run (function (){
    http.createServer (function (req, res){
        var dreq = domain.create ();
        dreq.add (req);
        dreq.add (res);
        dreq.on ("error", function (error){
            res.on ("close", function (){
                dreq.exit ();
            });
            res.writeHead (500);
            res.end ()
            console.error (error);
            dreq.exit();
        });
        dreq.run (function (){
            null.error
        });
    }).listen (1337, "localhost");
});

但是如果有1kk并发用户,数组/对象将有1kk属性,因为每个属性都有一个id。我还需要在服务器初始化期间捕获错误(在
listen()
函数之前的代码),您可以通过
error
事件捕获服务器错误。我在回答中更新了代码。我指的是使用
createServer()
创建服务器之前的错误,例如,在
require(“域”)之后写入
null。错误
。我执行一些异步任务,然后开始监听套接字。我需要在初始化过程中捕获这些错误。为什么不为这个异步任务使用单独的域,为服务器错误使用错误事件呢?因为这段代码非常简单。我真的需要将所有程序代码包装在一个域中
after
dreq.dispose()?!
var domain = require ("domain");
var http = require ("http");

var d = domain.create ();
d.on ("error", function (error){
    console.error (error);
});
d.run (function (){
    http.createServer (function (req, res){
        var dreq = domain.create ();
        dreq.add (req);
        dreq.add (res);
        dreq.on ("error", function (error){
            res.on ("close", function (){
                dreq.exit ();
            });
            res.writeHead (500);
            res.end ()
            console.error (error);
            dreq.exit();
        });
        dreq.run (function (){
            null.error
        });
    }).listen (1337, "localhost");
});