node.jsの最低限の例外処理

node.jsでサーバを立てる場合、アマPHPerな自分にとってはApacheを書くという今まで謎だった部分を実装するイメージになる。
だが、まずい実装をすると例外が発生し一発でサーバが簡単に落ちてしまい大トラブルになる。

例外処理対策、やった方が良さそうなことを集めていきたいと思います。

全体の例外処理設定

とりあえず全体の例外処理設定をする。

下記は例外処理を全くせずに、node.jsのデフォの挙動に頼った場合。

ar http = require('http');

http.createServer(
    function (request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.write('Hello World!!\n');
    response.end();
}).listen(8000);

hoge(); // 未定義。ここで落ちる

上記のコードだと、hogeを呼んだ時点で下記を出力して落ちる


node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
ReferenceError: hoge is not defined

例外処理(catchされなかった例外の処理)をメイン処理に追加

var http = require('http');

http.createServer(
    function (request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.write('Hello World!!\n');
    response.end();
}).listen(8000);

// 追加。catchされなかった例外の処理設定。
process.on('uncaughtException', function (err) {
    console.log('uncaughtException => ' + err);
});

hoge();

こうすると、


uncaughtException => ReferenceError: hoge is not defined
な感じで例外処理は起こしつつもサーバは稼動し続ける。
(落ちた方が良いこともあるだろうが)

この設定をしないと、クライアントの接続時など何らかのイベントループ内での例外でもサーバが落ちる。
この全体設定は、個別の処理でtry〜catchするのが一番良いんだろうが、漏れた部分の保険的な意味でも必ず設定しておく。

クライアントからの接続時

クライアント接続でのイベントループ内での例外は、先に書いたuncaughtExceptionを設定していてもまた別の懸念があります。

先の説明で「hoge」はサーバ本体処理(クライアント接続のイベントループの外)にいました。
今回は、クライアント接続のイベントループで例外を起こす「hoge()」をします。

var http = require('http');

http.createServer(
    function (request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});
    response.write('Hello World!!\n');
    hoge(); // クライアント接続中に例外を起こす
    response.end();
}).listen(8000);

process.on('uncaughtException', function (err) {
    console.log('uncaughtException => ' + err);
});

これに対しクライアントでcurlを実行
1.例外を起こす前までの処理「Hello World」の出力まではされる
2.hoge()で例外発生
3.切断処理が実行されずクライアント側は接続しっぱなし
となります。
下記の通り。


クライアント側
curl localhost:8000
Hello World!!
サーバ側
uncaughtException => ReferenceError: hoge is not defined
クライアント側
…接続切れず

なので、クライアント接続のイベントループで切断を妨げるような例外が発生する部分は特に気をつけ、
適切にtry〜catchしてその処理内で切断をしてやる必要がありそうです。

まとめ

何にしても、自分の実装するものを把握して例外が起こりえる部分はちゃんとtry〜catchしましょうという感じでした。
nodeに限ったことでは無いですが、nodeでは特にサーバ実装も自分で行う部分が多そうなので特に気をつけたいと思います。
また思いついたもの、経験をふまえてわかった物など追記していきたいと思います。

有識者の方、ご意見、ご指摘いろいろもらえたらうれしいです^^;