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。错误。我执行一些异步任务,然后开始监听套接字。我需要在初始化过程中捕获这些错误。为什么不为这个异步任务使用单独的域,为服务器错误使用错误事件呢?因为这段代码非常简单。我真的需要将所有程序代码包装在一个域中
afterdreq.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");
});