NestJS/NestJS 문서화

예외 필터

남느 2025. 4. 24. 15:29

예외 필터의 역할

NestJS의 예외 필터는 예외처리를 담당합니다.

예외 필터의 특징

직접 구현할 일은 거의 없습니다.

HTTP / GraphQL, 웹소켓, gRPC의 예외 코드가 다르기 때문에 하나의 서비스를 여러 프로토콜에서 사용한다면 사용자 정의 필터를 사용해야 합니다.

기본 제공 필터 목록

아래 필터들은 HTTP / GraphQL 에러를 발생시킵니다.

자주 사용할 것 같은 메서드만 정리했습니다.

전체 목록은 공식 문서에서 확인 하세요.

메서드 응답코드 설명
BadRequestException 400 요청이 잘못된 경우
UnauthorizedException 401 권한이 없을 때
ForbiddenException 403 서버가 요청을 거부
NotFoundException 404 서버는 정상이지만 요청한 정보가 없는 경우
RequestTimeoutException 408 요청 시간 초과
InternalServerErrorException 500 서버 내부의 오류
BadGatewayException 502 게이트웨이가 서버에서 잘못된 응답을 받았을 때
GatewayTimeoutException 504 게이트웨이가 서버에서 응답을 받지 못 할 때

필터 사용 예시

아래 두 코드는 똑같은 기능을 합니다.

기본 제공 필터 사용

@Get()
async findAll() {
  throw new ForbiddenException('Forbidden');
}

HttpException() 사용

@Get()
async findAll() {
  throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}

사용자 정의 필터 정의 방법

예외 처리 시 로그를 남기거나, 응답 JSON을 변경하기 위해 사용자 정의 필터를 정의하고 사용할 수 있습니다.

 

모든 필터는 ExceptionFilter<T> 인터페이스를 구현해야 합니다.

ExceptionFilter 인터페이스는 catch(exception: T, host: ArgumentsHost) 메서드를 구현해야 합니다.

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();
	
    // 로그 추가
    console.log(response);
    console.log(request);
    console.log(status);
    
    // 응답 변경
    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}

사용자 정의 필터 사용 방법

메서드에 적용 시

@Post()
@UseFilters(new HttpExceptionFilter())
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}

컨트롤러에 적용 시

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

글로벌 적용 시

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();