我有类似的东西:
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
不会发出,错误发生在执行时,它是一个 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 个执行了引发错误的任务,则发射器将执行所有错误处理程序,当只有 1 个用户应该收到 500 时,5 个用户将收到 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
对象的引用,如何在域错误处理程序中向用户发送错误?