最近在项目里发现一个奇怪的问题,我们使用nodejs去访问mysql或者redis的时候,如果回调函数出错了,domain居然抓不到,很纳闷,于是我模拟了一个这样的场景来说明这个问题。我先说一下运行过程,下面会贴出来两段代码,先运行server.js(这是一个类似redis的服务),然后运行server2.js(这个是web server服务),然后通过浏览器访问localhost:8080,第一次能看到被domain抓住了,然后打印了出错信息,但是当你再次刷新浏览器的时候,你会发现抛出的错误没被domain抓到,于是进程就退出了。。大家一起研究研究,这到是什么问题。。
server.js
var net = require('net');
net.createServer(function(conn){
console.log("new client");
conn.on("data", function(chunk){
console.log("data:", chunk.toString());
conn.write("hi " + chunk);//这里模拟数据处理完毕并且返回数据
});
conn.on("close", function(){
console.log("client end");
});
}).listen(1104);
server2.js
var net = require('net'),
http = require('http'),
domain = require('domain');
var conn = null;
function getConnection(cb)
{
if(conn){
cb(conn);
}else{
var client = new net.Socket();
client.connect(1104);
client.on("connect", function(){
conn = client;
cb(conn);
});
client.on("data", function(chunk){
console.log("recv data");
throw new Error("process error");//这里模拟回调出错
});
client.on("end", function(){
conn = null;
consoel.log("conn end");
});
}
}
http.createServer(function(req, res){
var reqd = domain.create();
reqd.on("error", function(err){
console.log("Domain Error:", err.stack);
reqd.dispose();
});
reqd.run(function(){
getConnection(function(conn){
conn.write("test", function(){
console.log("write end");
});
});
});
}).listen(8080);