[NestJS] - 24. NestJS 예외 처리와 필터(Filter) 적용

2023. 3. 5. 21:35
반응형

 

프로젝트를 운영하다 보면 예상치 못한 오류가 발생할 수 있다. 예외를 완전히 막을 수 있다면 좋겠지만 현실적으로는 불가능하다. 그렇다면 우리가 해야 하는 것은 예상치 못한 오류가 발생해도 프로젝트 전체에 악영향을 주지 못하게, 그리고 예외를 추적하여 빠르게 소스코드를 수정할 수 있도록 해야 할 것이다.

 

이번에는 예외가 발생하는 경우, 자동으로 Catch받아 예외 처리를 해주는 Exception Filter를 적용해 보려고 한다.

 


필터 작성하기

 

/src/commons/filter/http-exception.filter.ts

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

import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  constructor(private readonly logger: LoggerService) {
    //
  }
  catch(exception: HttpException, host: ArgumentsHost) {
    const status = exception.getStatus();
    const message = exception.message;

    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    if (
      status === HttpStatus.UNAUTHORIZED ||
      status === HttpStatus.NOT_FOUND ||
      status === HttpStatus.CONFLICT
    ) {
      this.logger.warn(
        `[CODE : ${status}] [${request.method} : ${request.url}] / [${message}] `,
      );
    } else {
      this.logger.error(
        `[CODE : ${status}] [${request.method} : ${request.url}] / [${message}] `,
      );
    }

    response.status(status).json({
      statusCode: status,
      message: message
      path: request.url,
    });
  }
}

 

  • NestJS에서 제공해주는 ExceptionFilter 인터페이스를 구현한 클래스를 생성해주었다.
  • 해당 필터는 HTTP Exception이 발생했을 모든 경우, 클라이언트에게 에러 인포를 반환해주며, 에러 코드에 따라서 Winston에 warn 혹은 error 로깅을 하려는 목적으로 작성되었다.
  • 데코레이터 @Catch(예외 종류)를 통해서 처리할 예외를 명시해준다.
  • catch() 메서드 안쪽에서 예외가 발생했을 경우 로직을 작성한다.

 

 


Global 필터로 사용하기

 

 main.ts

 

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './commons/filter/http-exception.filter';
import { winstonLogger } from './utils/winston/winston.config';

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

  const logger = winstonLogger;
  app.useLogger(logger);
  //...
  app.useGlobalFilters(new HttpExceptionFilter(logger));
  await app.listen(3000);
}
bootstrap();
  • 구현한 Filter 클래스를 main.ts에서 전역적으로 예외처리를 하도록 GlobalFilter로서 등록해준다.
  • app.useGlobalFilters(커스텀 필터) 를 통해서 글로벌 필터 등록을 한다.

 

 


적용 결과

 

예외에 대한 로그가 찍히는 것을 확인할 수 있다.

 

 

Exception 발생 시 클라이언트에 예외에 대한 정보를 반환한다.

 

반응형

BELATED ARTICLES

more