如何在域error handling程序中发送响应

我有类似的东西:

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错误,但在error handling程序中,我无法访问响应对象。


我的第一个尝试是为每个请求使用一个明确的域作为文档说:

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

dreqerror handling程序永远不会被调用,因为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"); }); 

这工作,错误捕获在error handling程序,然后发射,所以我可以使用响应对象发送消息给用户。 如果您对node.js基础知识了解甚less,则会看到此解决方法完全被窃听。 如果在事件循环中有5个用户请求,其中1个发出错误的任务,发射器将执行所有的error handling程序,5个用户将被通知500错误,当其中只有1个应该收到500错误。


我最后一次尝试是为每个请求创build子上下文。 文件没有提到这种模式。 这对我来说有点困惑:

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

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

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

我介绍内存泄漏?


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


如果我不能保存对res对象的引用,那么我怎样才能向域error handling程序中的用户发送一个错误?

这个解决scheme是赢家:

 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

你上次发布解决scheme实际上是你应该做的。 这不同于文档build议的嵌套types。 你所要做的就是将潜在的(或者在这种情况下,肯定是)错误的代码包装在域中,这样当错误被域所处理时,

这个解决scheme适用于我:

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