Expressの冗長なエラー処理を簡潔にする

Expressの冗長なエラー処理を簡潔にする:

初投稿です。

今までExpressのエラー処理は以下のように書いてました。

(例:必須のリクエストパラメータのチェック)

const { username } = req.body; 
if (!username) { 
  const err = new Error('username is required'); 
  console.log(err); 
  res.status(400).send({ error: err }); 
} 
パラメータの個数分、同様の処理を書いていて冗長だなぁと感じていました。


エラー処理ミドルウェア関数

Express でのエラー処理にエラーハンドリングの方法が書いてありました。

err, req, res, nextの4つの引数を持つミドルウェア関数を定義して、全てのミドルウェアの最後で呼び出します。

function logErrors(err, req, res, next) { 
  console.error(err.stack); 
  next(err); 
} 
 
function errorHandler(err, req, res, next) { 
  res.status(500); 
  res.send({ error: err }); 
} 
 
app.use(logErrors); 
app.use(errorHandler); 
logErrors関数はエラーのログを出力します。

errorHandler関数はクライアントにエラーレスポンスを返します。

そして、エラーを投げる側ではnext関数にエラーオブジェクトを渡します。

const { username } = req.body; 
if (!username) { 
  const err = new Error('username is required'); 
  next(err); 
} 
これでエラーログ出力とエラーレスポンス返却をエラー処理ミドルウェアに任せることができました。

しかし、今のままではerrorHandlerで常にステータスコードが500のエラーレスポンスが返されてしまいます。なので、ちょっと変えます。

function errorHandler(err, req, res, next) { 
  res.status(err.statusCode || 500); 
  res.send({ error: err }); 
} 
const { username } = req.body; 
if (!username) { 
  const err = new Error('username is required'); 
  err.statusCode = 400; 
  next(err); 
} 
これでステータスコードが400のエラーレスポンスを返せるようになります。


ステータスコードの設定

毎回、エラーオブジェクトにステータスコードを設定するのは面倒臭いです。

CustomErrorクラスかboomを導入すると、ステータスコードの設定が簡潔になります。


CustomErrorクラス

class CustomError extends Error { 
  constructor(message, statusCode) { 
    super(message); 
    this.statusCode = statusCode; 
  } 
} 
if (!username) next(new CustomError('username is required', 400)); 
ワンライナーで書けました。


boom

hapijs/boom

boomはHTTPのエラーオブジェクト返すモジュール群です。

Boom.badRequest('invalid query') 
上のコードは以下のオブジェクトを返します。

{ 
    "statusCode": 400, 
    "error": "Bad Request", 
    "message": "invalid query" 
} 
コードを見ればどんなエラーかわかるのでいいですね。

badRequestの他にもunauthorizedやnotFoundなど基本的なエラーが揃っています。

boomを使って書くと、こうなります。

if (!username) next(Boom.badRequest('username is required')); 


まとめ

  • エラーミドルウェア関数を用いることで、エラーログ出力とエラーレスポンスの返却処理を共通化することができました
  • CustomErrorクラス(またはboom)を用いることで、ステータスコードの設定が簡単になりました


参考

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)