2012年11月18日日曜日

[node.js + express]express で エラーをハンドルするミドルウェアを作成する

エラーハンドル用のミドルウェア


エラーハンドル用のミドルウェアと通常のミドルウェアとの違いは、受け取る引数の数です。
エラーハンドル用のミドルウェアは、引数を4つ受け取ります。1番目の引数に渡されるのは、エラーオブジェクトです。

(2012/12/01 追記)エラーハンドル用のミドルウェアは、通常ミドルウェアのチェーンの最後尾で定義します。

app.js
app.configure(function(){

  //省略

  app.use(function(err, req, res, next){
    console.error(err.stack);
    res.send(500, "エラーが発生しました。")
  })
})

(2012/12/01 追記)エラーハンドル用ミドルウェアに処理を渡す


エラーハンドル用ミドルウェアに処理を渡すには、next の引数にエラーオブジェクトを渡して呼び出します。
例えば、routes 内で発生したエラーをエラーハンドルようミドルウェアに渡したい場合は、下記の用に next を呼び出します。
app.get('/entries', function(req, res, next){
  Entry.find(function(err){
    if (err) next(err);

    //通常の処理
  );
);

複数のエラーハンドル用ミドルウェアを連結する


複数のエラーハンドル用ミドルウェアを連結させる場合も、 next に err を渡して次のミドルウェアを呼び出します。
これにより、特定のエラーのみ処理するミドルウェアを作るなど、より細かくエラー処理を制御できます。

下の例では、3つのエラーハンドル用ミドルウェアを定義していますが、それぞれのミドルウェアでは、

  • 標準エラー出力にエラー内容を書き出す
  • XMLHttpRequest のリクエストに対する処理で発生したエラーの場合は 、 json でメッセージを返す
  • それ以外のエラーでは、専用のエラーページを表示させる

という処理を行っています。

app.js
app.configure(function(){

  //省略

  app.use(function(err, req, res, next){
      console.error(err.stack);
      next(err);
  });

  app.use(function(err, req, res, next){
    if(req.xhr){
      res.json(500, {message: err.message, stack: err.stack});

    } else {
      next(err)
    }
  })

  app.use(function(err, req, res, next){
    console.error(err.stack);
    res.status(500);
    res.render('500', {title: "エラーが発生しました。"});
  })
})


Connect の errorHandler ミドルウェア


ちなみに、express new コマンドで生成したアプリケーションのデフォルトでは、エラーが発生すると、エラー内容がコンソールに表示され、見やすいエラーページが表示されます。
この処理を行っているのは、 app.configure で設定されている、 Connect の errorHandler ミドルウェア(http://www.senchalabs.org/connect/errorHandler.html)です。

app.js
app.configure('development', function(){
  app.use(express.errorHandler());
});

まとめ


エラーハンドリング用のミドルウェアは、4つの引数を受け取り、最初の引数にエラーオブジェクトが渡される。
エラーハンドリングのミドルウェアを連結させる場合は、エラーオブジェクトを渡した next を呼び出す。


参照URL
http://expressjs.com/guide.html#error-handling

0 件のコメント:

コメントを投稿