uncaughtExceptionのハンドラの中で例外発生させたときの挙動

基本的には、プログラムで例外が発生したときに、それがcatchされないとプログラムは終了する(落ちる)。
しかし、実際に運用する環境のプログラムでは、仮にcatchされなかったとしてもプログラムを止めることはできないので、
どうにかする。

Node.jsの場合は次のように、プログラム中でcatchされなかった例外を最も低レベルで捕捉することができる。

process.on('uncaughtException', function(err) {
    console.log('an error occured', err);
});

processはNode.js上ではグローバル変数である。
なお注意として、この方法は現在推奨されておらず、将来削除される可能性があるとのこと。

Note that uncaughtException is a very crude mechanism for exception handling and may be removed in the future.

Don't use it, use domains instead. If you do use it, restart your application after every unhandled exception!

http://nodejs.org/api/process.html#process_event_uncaughtexception

uncaughtExceptionをハンドルするコールバック関数内で、uncaughtなExceptionを発生させたらどうなるか

無限ループが起こりそうな気がするが、
しかし例えば来たものをそのまま投げるだけのときとかもあるので、無限ループされても困る気がする。

実際に試してみた。

process.on('uncaughtException', function(err) {
    console.log('an error occured', err);
    throw err;
});
throw new Error('foo'); // トリガを引く

結果

an error occured [Error: foo]

            throw err;
                  ^
Error: foo
    at Object.<anonymous> (/foo/bar/uncaught_exception_test/server.js:4:15)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

uncaughtExceptionのハンドラ内で単純に例外をスローした場合、その例外はもはや捕捉されることなく、プログラムは終了するということがわかった。

それでは、単純にスローせず、非同期関数を1枚かぶせるとどうなるか

process.on('uncaughtException', function(err) {
    console.log('an error occured', err);
    // 次の行は非同期関数ならなんでもいい
    fs.stat('./app.js', function() {
        throw err;
    });
});
throw new Error('foo');

結果

an error occured [Error: foo]
an error occured [Error: foo]
an error occured [Error: foo]
an error occured [Error: foo]
an error occured [Error: foo]
...

というわけで、めでたく無限ループになった。(当たり前といえば当たり前)
したがって、このハンドラ内で外部への通知などちょっと凝ったことをする場合は、注意しなければならない。

この辺の挙動はおそらく、Node.jsのイベントループについてもっと詳しく知っていれば調べるまでもないのだろうから、
きちんと知っておかないとなぁ。