高瀬博道の技術ブログ

高瀬博道の技術ブログです。

もう2023年になったので、今さらNestJSに入門しようと思う - その10

前回

takasehiromichiex.com

組み込みのHTTP例外

Nestは、一連の標準例外を提供しています。

  • BadRequestException
  • UnauthorizedException
  • NotFoundException
  • ForbiddenException
  • NotAcceptableException
  • RequestTimeoutException
  • ConflictException
  • GoneException
  • HttpVersionNotSupportedException
  • PayloadTooLargeException
  • UnsupportedMediaTypeException
  • UnprocessableEntityException
  • InternalServerErrorException
  • NotImplementedException
  • ImTeapotException
  • MethodNotAllowedException
  • BadGatewayException
  • ServiceUnavailableException
  • GatewayTimeoutException
  • PreconditionFailedException

例外フィルタ

組み込み例外フィルタは多くのケースを自動的に処理できますが、例外レイヤーを完全に制御したい場合は、例外フィルタを使用します。

フィルタを作成してみましょう。

$ nest g filter filter/http

以下のファイルが生成されます。

src/filter/http/http.filter.ts
import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common';

@Catch()
export class HttpFilter<T> implements ExceptionFilter {
  catch(exception: T, host: ArgumentsHost) {}
}
src/filter/http/http.filter.spec.ts
import { HttpFilter } from './http.filter';

describe('HttpFilter', () => {
  it('should be defined', () => {
    expect(new HttpFilter()).toBeDefined();
  });
});

フィルタを少し書き換えてみましょう。

src/filter/http/http.filter.ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

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

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

作成したフィルタをコントローラにバインドしましょう。

src/cats/cats.controller.ts
import { Controller, Get, HttpException, HttpStatus, UseFilters } from '@nestjs/common';
import { CustomException } from 'src/exception/custom.exception';
import { HttpFilter } from '../filter/http/http.filter';

@Controller('cats')
export class CatsController {
    @Get()
    @UseFilters(new HttpFilter())
    findAll() {
        throw new CustomException();
    }
}

このAPIを呼ぶと、以下のように返却されます。

{
    "statusCode": 403,
    "timestamp": "2023-01-08T11:13:51.726Z",
    "path": "/cats"
}

まとめ

ここまでで、

  • 組み込みのHTTP例外について
  • 例外フィルタについて

を学びました。

次回は、パイプについて掘り下げようと思います。

コード

今回のコードは、以下に格納しました。

github.com

takasehiromichiex.com