[Nest.js] exception filter 파헤치기

김지엽·2023년 12월 13일
0
post-thumbnail

1. 개요

express 프로젝트 중 문득 궁금한게 생겼다. express 같은 경우 예기치 않은 에러가 발생했을때 try-catch등으로 방지를 안했을 경우 서버가 종료된다. 이는 매우 치명적으로 다가올 수 있기 때문에 꼭 try-catch등으로 예기치 않은 에러를 대비해야 한다.

하지만 nest에서는 controller-layer에서 try-catch 등으로 에러를 처리해주지 않아도 자동으로 Internal server error를 응답한다.

아마도 exception filter가 처리해주는 것으로 보이는데 정확히 알고있지 않기에 자세하게 공부해 볼려고 한다.

2. global exception filter

nestJs 공식문서에 따르면 다음과 같다.

위 내용을 요약하면 다음과 같다.

  1. nest에서는 전역 예외 필터가 내장되어 있다.
  2. 전역 예외 필터는 http 예외가 throw될 경우 status와 message에 맞게 적절한 응답을 한다.
  3. 전역 예외 필터는 http 예외가 아닌 예기치 않은 에러가 throw될 경우 Internal server error를 응답한다.

3. HttpException

- express의 경우

express에서는 status와 message를 함께 담아 error를 throw할 경우 다음과 같이 코드를 작성해야 한다.

const error = new Error("존재하지 않는 예약 정보입니다.");
error.status = 404;
throw error;

하지만 모든 error에 대해 일일히 코드를 작성하면 번거롭기에 별도의 class를 생성해서 코드를 간략하게 한다.

// 별도 클래스 작성
export class HttpException extends Error {
    constructor(status, message) {
        super(message);
        this.status = status;
    }
}

// 코드 간략화 및 가독성 높이기
throw new HttpException(404, "존재하지 않는 예약 정보입니다.");

- nest의 경우

nest에서는 express와 달리 대부분의 Http 예외가 내장되어 있다.

다음과 같이 내장되어 있는 HttpException을 사용해 예외를 처리 할수 있다.

// forbidden
throw new HttpException({
  status: HttpStatus.FORBIDDEN,
  error: 'This is a custom message',
}, HttpStatus.FORBIDDEN, {
  cause: error
});

그리고 또한 코드의 가독성 및 효율성을 높여주는 커스텀 예외 또한 존재한다.

// forbidden
throw new ForbiddenException();

nest는 기본적으로 다음과 같은 커스텀 예외를 지원하며 이를 활용하는 것은 코드에 매우 도움이 될 것이다.

4. custom exception filter

기본적으로 내장되어 있는 예외 필터의 응답을 바꾸고 싶거나 예외가 발생했을때 특정 기능을 수행하고 싶을경우 직접 exception filter를 작성할 수 있다.

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 + "<- 여기서 발생한 에러임",
      });
  }
}

위와 같이 추가적으로 응답을 수정하거나 혹은 다른 기능을 수행하는 방향으로 커스터함 예외 필터를 작성할 수도 있다.

참고

nest 공식문서

profile
욕심 많은 개발자

0개의 댓글