如何发送域的错误处理

如何发送域的错误处理

问题描述:

内作出答复有一些与此类似:如何发送域的错误处理

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错误处理程序不会被调用,因为reqres绝不会发出,在执行中发生错误这是一个TypeError。


我的第二个尝试是使用封闭件保存到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个请求发出错误,则发射器将执行所有错误处理程序,并且只有其中一个应收到500个错误错误。


我最后的尝试是为每个请求创建子上下文。文档没有提到这种模式。这对我有点困惑:

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

如果要将域对象嵌套为父域的子对象,则必须明确地添加它们,然后再处置它们。

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.on ("error", function (error){ 
      res.writeHead (500); 
      res.end() 
      console.error (error); 
      dreq.dispose(); 
     }); 
     dreq.run (function(){ 
      null.error 
      //... 
      //dreq.dispose(); 
     }); 
    }).listen (1337, "localhost"); 
}); 

上午我介绍内存泄漏?


的简单的解决方案将是,以一个唯一的ID分配给每个请求,并将它们保存在一个对象或一个数组,并且当发射器发射发现必须执行给定的唯一ID的处理程序。完全不能接受。


如果我不能保存到res对象的引用,我怎么能发送错误域错误处理程序中的用户?

+0

加上'DREQ = NULL;'dreq.dispose后'(); '?! – xrDDDD 2013-07-05 17:28:28

该解决方案是赢家:

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"); 
}); 

https://github.com/joyent/node/issues/4905

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

+0

但是,如果有1kk的并发用户,则数组/对象将具有1kk的属性,因为它们中的每一个都会有一个id。 – 2013-03-03 10:11:04

该解决方案为我工作得很好:

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); 
}); 
+0

我还需要捕获服务器初始化期间的错误('listen()'函数之前的代码) – 2013-03-03 10:13:05

+0

您可以使用'error'事件捕获服务器错误。我在回答中更新代码。 – 2013-03-03 10:30:43

+0

我的意思是在使用'createServer()'创建服务器之前的错误,例如,在'require(“domain”)'之后写入'null.error'。我做了一些异步任务,然后开始监听套接字。我需要在初始化期间捕获这些错误。 – 2013-03-03 11:05:22