Nest.js例外フィルタを使用してエラーを処理する方法

Nest.js例外フィルタは、グローバルまたはコントローラごとに例外をインターセプトして処理する方法を提供します。

エラー処理ロジックを一元化し、エラー応答の形式を設定し、アプリケーション全体で一貫したエラー処理を提供します。例外フィルタとその適切なアプリケーションエラー処理方法について説明します。

Nest.jsのデフォルトエラー処理

デフォルトでは、Nest.jsには、アプリケーションコードで処理されない例外を処理する例外レイヤーがあります。

アプリケーションで未処理のエラーが発生すると、Nest.jsはそれをキャッチして、クライアントに500の内部サーバーエラーを返します。この場合、Nest.jsが返すJSONは次のようになります。

{
"statusCode": 500,
"message": "Internal server error"
}

コードがスローするエラーオブジェクトにstatusCodemessageが含まれている場合、Nest.jsはそれらの値をデフォルトの応答の代わりに返します。

この一般的な動作を回避し、より意味のあるエラー応答をクライアントに送信するには、アプリケーションで発生する可能性のあるすべてのエラーを注意深く処理する必要があります。これは、Nest.jsの組み込みまたはカスタム例外フィルタを使用して実現できます。

カスタム例外フィルタの作成

カスタム例外フィルタを作成するプロセスを実証するために、すべてのHTTP例外を処理するフィルタを作成してみましょう。

http.exception.tsというファイルから始めて、それに次のインポートを追加します。

import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';

import { Request, Response } from 'express';

これらのインポートは、次の目的を果たします。

  • ExceptionFilter: これは、例外フィルタの実装を記述するインターフェースです。
  • Catch: これは、クラスをNest例外フィルタとしてマークするデコレータです。
  • ArgumentsHost: このインターフェースは、ハンドラに渡された引数を取得するためのメソッドを提供します。引数を取得するのに適した実行コンテキスト(HTTP、RPC、またはWebSocketsなど)を選択できます。
  • HttpException: これは、基本的なNest HTTP例外を定義するクラスです。
  • RequestResponse: これらは、それぞれExpress.jsのリクエストオブジェクトとレスポンスオブジェクトのインターフェースです。

次に、ExceptionFilterを実装するHttpExceptionFilterというクラスを作成します。Catchデコレータで注釈を付け、それがHttpExceptionを処理することを示します。

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}

次に、このコードでクラスを設定します。

catch(exception: HttpException, host: ArgumentsHost) {
// ArgumentsHostオブジェクトからレスポンスオブジェクトを取得します
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();

// ArgumentsHostオブジェクトからリクエストオブジェクトを取得します
const request = ctx.getRequest<Request>();

// 例外からステータスコードを取得します
const status = exception.getStatus();

// レスポンスオブジェクトを使用してJSON応答を送信します
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message:
exception.message
|| exception.getResponse()['message']
|| 'Internal Server Error',
});
}

このコードブロックは、ArgumentsHostオブジェクトからリクエストとレスポンスのオブジェクトを取得し、例外から関連情報を抽出します。クライアントに、エラーに関する詳細情報を含む構造化されたJSONオブジェクト応答を返します。

例外フィルタのバインド

必要に応じて、例外フィルタをコントローラまたはアプリケーション全体にバインドできます。

例外フィルタをグローバルにバインドするには、まずmain.tsファイルに例外フィルタをインポートします。次に、例外フィルタのインスタンスをapp.useGlobalFiltersメソッドに渡します。

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './exception/http.exception';

async function bootstrap() {
const app = await NestFactory.create(AppModule);

// フィルタをアプリケーションにバインドします
app.useGlobalFilters(new HttpExceptionFilter());

await app.listen(4050);
}

bootstrap();

例外をコントローラにバインドするには、UseFiltersデコレータと例外フィルタをインポートします。@UseFiltersデコレータでコントローラクラスに注釈を付け、デコレータに例外フィルタのインスタンスをアーギュメントとして渡します。

@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}

フィルタをバインドする場所によって、エラー処理の範囲が決まります。コントローラにバインドされたフィルタは、バインドされたコントローラのみを処理し、アプリケーションにバインドされたフィルタはアプリケーション全体を処理します。

組み込み例外を使用してエラーをスローする

Nest.jsは、エラーをスローするために使用できる組み込みの例外クラスを提供します。

たとえば、NotFoundExceptionクラスを使用して404ステータスコードのエラーをスローできます。

getUserById(id: number) {const user = users.find((user) => user.id === id);if (!user) {throw new NotFoundException({message: IDが${id}のユーザーが見つかりません,});}}

このコードブロックは、条件付きステートメントを使用して、指定されたユーザーが存在するかどうかを確認します。存在しない場合、NotFoundExceptionを使用して404エラーをスローし、メッセージをアーギュメントとして渡します。

一般的な組み込み例外クラス

他の組み込み例外クラスには、以下のようなものがあります(これらに限定されません)。

  • BadRequestException: ステータスコード400の不正なリクエストを示す例外をスローします。この例外は、クライアントのリクエストが無効または不正であり、サーバーがクライアントのエラーのために処理できない場合に使用できます。通常、クライアントがリクエストを修正して有効にする必要があることを意味します。
  • UnauthorizedException: ステータスコード401の不正なアクセスを示す例外をスローします。この例外は、ユーザーが認証されていないか、リソースにアクセスするために必要なアクセス許可がない場合に使用できます。
  • ForbiddenException: ステータスコード403の禁止されたアクセスを示す例外をスローします。この例外は、ユーザーが認証されているが、特定のアクションを実行する権限がない場合に使用できます。
  • RequestTimeoutException: ステータスコード408のリクエストタイムアウトを示す例外をスローします。この例外は、サーバーが処理に時間がかかりすぎるためにリクエストを終了した場合に使用できます。
  • ConflictException: ステータスコード409の競合を示す例外をスローします。この例外は、クライアントのリクエストとリソースの現在の状態との間に競合がある場合に使用できます。たとえば、すでに存在するリソースを作成しようとした場合などです。
  • InternalServerErrorException: ステータスコード500の内部サーバーエラーを示す例外をスローします。この例外は、サーバー側で予期しないエラーが発生し、サーバーが内部の問題のためにリクエストを処理できないことを示す場合に使用できます。

Nest.jsでのエラー処理のベストプラクティス

Nest.jsでエラーを処理する場合、例外フィルタを使用して例外をグローバルに、またはコントローラごとにキャッチして処理するようにしてください。特定の例外タイプのカスタムフィルタを作成することもできます。

さらに、適切な組み込み例外クラスを使用して適切で意味のあるエラーをスローするようにしてください。これらのプラクティスは、Nest.jsアプリの信頼性を大幅に向上させることができます。