NestJSの例外フィルターの作成と利用

NestJSでの例外フィルターの作成と利用方法を学びましょう。

概要

NestJSでは、例外フィルターを利用して、例外が発生した際の処理をカスタマイズすることができます。例外フィルターは、例外が発生したときに呼び出され、例外の内容に基づいて適切なレスポンスを生成します。

例外フィルターを作成する方法

例外フィルターを作成するには、まずExceptionFilterインターフェースを実装したクラスを作成します。このインターフェースは、catchメソッドを持ち、このメソッドは例外とホスト(HTTPリクエストとレスポンスの情報を持つオブジェクト)を引数に取ります。 以下に、独自の例外フィルターを作成する例を示します。

以下コマンド実行し、例外フィルターを作成します。

nest g f users/filters/http-exception

/src/common/filters/http-exception/http-exception.filter.ts

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

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}

上記のコードでは、HttpExceptionFilterという名前の例外フィルターを作成しています。このフィルターは、HttpExceptionがスローされたときに呼び出されます。

例外フィルターを利用する方法

作成した例外フィルターを利用するには、@UseFiltersデコレータを使用します。このデコレータをメソッドやコントローラーに適用することで、その範囲で発生した例外をフィルターで処理することができます。

以下に、作成した例外フィルターを利用する例を示します。

/src/users/users.controller.ts

import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  HttpException,
  HttpStatus,
  UseFilters,
} from '@nestjs/common';
import { UsersService } from './users.service';
import { ForbiddenException } from './exceptions/forbidden.exception';
import { HttpExceptionFilter } from './filters/http-exception.filter';


@Controller('users')
@UseFilters(new HttpExceptionFilter())
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  getUsers(): User[] {
    return this.usersService.getUsers();
  }

  @Post()
  addUser(@Body() name: string): void {
    this.usersService.addUser(name);
  }

  @Put(':id')
  putUser(@Param('id') id: number, @Body('name') name: string): void {
    this.usersService.putUser(id, name);
  }

  @Delete(':id')
  deleteUser(@Param('id') id: number): void {
    this.usersService.deleteUser(id);
  }
  @Get('throw')
  getException(): string {
    throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
  }
  @Get('custom_throw')
  getCustomException(): string {
    throw new ForbiddenException();
  }
}

上記のコードでは、UsersController全体でHttpExceptionFilterを適用しています。これにより、このコントローラー内で発生したHttpExceptionはすべてHttpExceptionFilterで処理されます。

テスト

$ curl http://localhost:3000/users/throw
## 出力
{"statusCode":403,"timestamp":"2021-07-11T14:41:39.000Z","path":"/users/throw"}

まとめ

NestJSでは、例外フィルターを利用して、例外が発生した際の処理をカスタマイズすることができます。例外フィルターは、例外が発生したときに呼び出され、例外の内容に基づいて適切なレスポンスを生成します。これにより、エラーハンドリングをより柔軟に行うことができます。