Expressを使用してRESTAPIを強化しているため、私のユースケースではカスタムJSONエラーメッセージを送信しています。これはかなり一般的なシナリオだと思うので、私の答えではそれに焦点を当てます。
短縮版:
Expressエラー処理
エラー処理ミドルウェアを他のミドルウェアと同じように定義しますが、3つではなく4つの引数、特に署名(err、req、res、next)を使用します。...エラー処理ミドルウェアを最後に定義し、他のapp.use()とルーティング呼び出しの後に
app.use(function(err, req, res, next) {
if (err instanceof JSONError) {
res.status(err.status).json({
status: err.status,
message: err.message
});
} else {
next(err);
}
});
次の手順を実行して、コードの任意のポイントからエラーを発生させます。
var JSONError = require('./JSONError');
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
ロングバージョン
エラーをスローする標準的な方法は次のとおりです。
var err = new Error("Uh oh! Can't find something");
err.status = 404;
next(err)
デフォルトでは、Expressは、コード404とスタックトレースが追加されたメッセージ文字列で構成される本文を含むHTTP応答として適切にパッケージ化することでこれを処理します。
たとえば、ExpressをRESTサーバーとして使用している場合、これは機能しません。エラーをHTMLではなくJSONとして返送したいと思います。また、スタックトレースをクライアントに移動させたくないことも間違いありません。
req.json()
たとえば、JSONを応答として送信できます。のようなものreq.json({ status: 404, message: 'Uh oh! Can't find something'})
。オプションで、を使用してステータスコードを設定できますreq.status()
。2つを組み合わせる:
req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});
これは魅力のように機能します。とはいえ、エラーが発生するたびに入力するのは非常に扱いにくく、コードは以前のように自己文書化されなくなりましnext(err)
た。これは、通常の(つまり有効な)応答JSONが送信される方法と非常によく似ています。さらに、正規のアプローチによってスローされたエラーは、引き続きHTML出力になります。
ここで、Expressのエラー処理ミドルウェアが登場します。ルートの一部として、次のように定義します。
app.use(function(err, req, res, next) {
console.log('Someone tried to throw an error response');
});
また、ErrorをカスタムJSONErrorクラスにサブクラス化します。
JSONError = function (status, message) {
Error.prototype.constructor.call(this, status + ': ' + message);
this.status = status;
this.message = message;
};
JSONError.prototype = Object.create(Error);
JSONError.prototype.constructor = JSONError;
ここで、コードでエラーをスローしたい場合は、次のようにします。
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);
カスタムエラー処理ミドルウェアに戻り、次のように変更します。
app.use(function(err, req, res, next) {
if (err instanceof JSONError) {
res.status(err.status).json({
status: err.status,
message: err.message
});
} else {
next(err);
}
}
エラーをJSONErrorにサブクラス化することは重要です。これは、Expressがにinstanceof Error
渡された最初のパラメーターをチェックしてnext()
、通常のハンドラーまたはエラーハンドラーを呼び出す必要があるかどうかを判断するためです。instanceof JSONError
チェックを削除し、小さな変更を加えて、予期しないエラー(クラッシュなど)もJSON応答を返すようにすることができます。