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();
}
次に、モカなしで簡単なテストを作成しました。
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
ノードの問題はクローズされていますが、モカの問題はまだ開いています。
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 の問題の最後にコメントを追加して、解決できるかどうかを確認しました。
https://github.com/visionmedia/mocha/issues/513