Loading...
본문 바로가기
👥
총 방문자
📖
0개 이상
총 포스팅
🧑
오늘 방문자 수
📅
0일째
블로그 운영

여러분의 방문을 환영해요! 🎉

다양한 개발 지식을 쉽고 재미있게 알려드리는 블로그가 될게요. 함께 성장해요! 😊

코딩 정보/NestJs

[NestJs] Exception Filter를 구현해 보자

by 꽁이꽁설꽁돌 2025. 2. 10.
728x90
반응형
     

목차

    exception filter란?

    1. 예외 처리를 통합하고 중복 코드 줄이기

    NestJS에서는 throw new HttpException('Error', 400);처럼 예외를 발생시킬 수 있다. 하지만, 모든 컨트롤러에서 예외를 개별적으로 처리하면 코드가 중복되고 유지보수가 어려워진다.
    Exception Filter를 사용하면 특정 예외를 한 곳에서 처리하여 코드 중복을 방지할 수 있다.

     

    2. 다양한 예외를 한 곳에서 관리

    NestJS 기본 제공 HttpException 외에도 커스텀 예외 (DatabaseException, ValidationException 등) 를 만들 수 있다.
    이 경우 Exception Filter를 사용하면 다양한 예외를 하나의 필터에서 관리할 수 있다.

     

    3. 로깅 & 디버깅을 쉽게 하기

    Exception Filter를 활용하면 예외 발생 시 자동으로 로그를 남길 수 있다.
    이렇게 하면 예외 발생 시 원인을 추적하기가 쉬워진다.

     

    4. 보안 강화 (예외 메시지 감추기)

    기본적으로 NestJS는 HttpException의 메시지를 클라이언트에 그대로 노출한다.
    하지만 보안상 민감한 정보를 감추고, 사용자 친화적인 에러 메시지를 제공하려면 Exception Filter가 필요하다.

     

     

    HttpException 만들어 보기

    import {
      ArgumentsHost,
      Catch,
      ExceptionFilter,
      HttpException,
    } from '@nestjs/common';
    
    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
      //annotation에 있는 exception이 알아서 들어감
      catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse();
        const request = ctx.getRequest();
        const status = exception.getStatus();
    
        //로그 파일을 생성하거나
        // 에러 모니터링 시스템에 API 콜 하기
    
        response.status(status).json({
          statusCode: status,
          message: exception.message,
          timeStamp: new Date().toLocaleString('kr'),
          path: request.url,
        });
      }
    }

     

    이런식으로 적용한 뒤 임시로 에러를 발생시켜 보았다.

    @Controller('posts')
    export class PostsController {
      constructor(
        private readonly postsService: PostsService,
        private readonly postsImageService: PostsImagesService,
        private readonly dataSource: DataSource,
      ) {}
      @Get()
      @UseInterceptors(LogInterceptor)
      @UseFilters(HttpExceptionFilter)
      getPosts(@Query() query: paginatePostDto) {
        throw new BadRequestException('에러 테스트!');
         return this.postsService.getAllPosts();
      }

     

    원래 오류

     

    filter를 추가한 뒤 바뀐 오류 상태

     

     

    전역적으로 에러 추적 관리

    아래와 같이 app에 추가해 전역적으로 에러를 로깅하는데도 사용한다.

    import { NestFactory } from '@nestjs/core';
    import { AppModule } from './app.module';
    import { ValidationPipe } from '@nestjs/common';
    import { HttpExceptionFilter } from './common/exception-filter/http.exception-filter';
    
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      //변환하는 작업허가 요청
      app.useGlobalPipes(
        new ValidationPipe({
          //-> 기본값 설정 가능
          transform: true,
          // -> @Type() annotation을 쓰지 않아도 됨
          transformOptions: {
            enableImplicitConversion: true,
          },
          //데코레이터값이 아니면 안되게끔 설정
          whitelist: true,
          // //설정 안된 데코레이터면 그에 맞는 에러를 던져줌
          forbidNonWhitelisted: true,
        }),
      );
      app.useGlobalFilters(new HttpExceptionFilter());
      await app.listen(process.env.PORT ?? 3000);
    }
    bootstrap();

     

     

    강의출처

     

    반응형