nodejs 域确实可以捕获同步错误
看这个简单的测试用例
var domain = require("domain");
var d = domain.create();
d.on("error", function() {
console.log("domain caught");
});
d.run(function() {
throw new Error("foo");
});
// result: domain caught
编辑:自从写了这个答案后,我写了一篇博客文章,描述了域和 try catch 的情况以及是否可以使用域作为 try catch 的批发替代品。它总结了这里讨论的大部分内容。
http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/
原始答案:
其实摩卡有问题。
我写了以下测试函数:
function error(callback){
var d = domain.create().on('error', function(err){
console.log("Caught Error in Domain Handler")
return callback(err);
});
d.enter();
throw new Error("TestError");
d.exit();
}
然后我写了一个没有mocha的简单测试:
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
})
我收到的输出是:
Caught Error in Domain Handler
Error was returned
当我使用 Mocha 进行测试时:
describe('Domain Tests', function(){
it('Should return an error when testing', function(done){
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
return done();
})
});
});
我收到以下输出:
․
0 passing (4ms)
1 failing
1) Domain Tests Should return an error when testing:
Error: TestError
at error (/Users/bensudbury/Documents/node_projects/testMochaDomains/test.js:9:11)
at Context.<anonymous> (/Users/bensudbury/Documents/node_projects/testMochaDomains/testMocha.js:6:3)
at Test.Runnable.run (/usr/local/share/npm/lib/node_modules/mocha/lib/runnable.js:194:15)
at Runner.runTest (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:358:10)
at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:404:12
at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:284:14)
at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:293:7
at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:237:23)
at Object._onImmediate (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:261:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)
如您所见:域错误处理程序短路。
此问题似乎与以下问题有关:
https://github.com/visionmedia/mocha/issues/513
虽然 Node 问题已关闭,但 mocha 中的问题仍然存在。
在这种情况下,建议的解决方法是:https ://gist.github.com/mcollina/4443963并没有解决问题。
我翻遍了 Mocha 的代码,发现问题的出现是因为 mocha 将测试包装在 try catch 块中。这意味着异常被捕获并且永远不会发送到 uncaughtException 或 _fatalException 处理程序,具体取决于您使用的节点版本。
您的解决方法很好,但是nodejs 域肯定会捕获同步错误,所以我不会更改您的代码,而是更改您的测试。您的新测试应如下所示:
describe("test", function() {
it("should succeed", function(done) {
process.nextTick(function(){
var foo = require("./foo.js");
foo(function() {
console.log("done");
done();
});
})
});
});
我尚未测试此代码,但我的示例的类似代码可以正常工作:
it('Should return an error when testing', function(done){
process.nextTick(function(){
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
return done();
});
})
});
我在 Mocha 的 issue 末尾添加了一条评论,看看是否可以解决:
https://github.com/visionmedia/mocha/issues/513