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个错误时,将通知500个用户500个错误错误.
我的最后一次尝试是为每个请求创建子上下文.文档没有说明这种模式.这对我来说有点混乱:
In order to prevent excessive memory usage, Domain objects themselves are not implicitly added as children of the active domain. If they were, then it would be too easy to prevent request and response objects from being properly garbage collected.
If you want to nest Domain objects as children of a parent Domain, then you must explicitly add them, and then dispose of them later.
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对象的引用,我如何向域错误处理程序内的用户发送错误?
这个解决方案是赢家: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