Nest.js에서 전역으로 에러 처리하기 🧨

yiyb0603·2021년 3월 17일
6

Nest.js

목록 보기
3/4
post-thumbnail

안녕하세요 오늘은 Nest.js에서 전역으로 에러 처리하기라는 주제로 글을 작성해보도록 하겠습니다.
기존에 많이 사용했던 Express.js에서는 일일히 try / catch를 걸어주면서 검증 오류인지, 서버 오류인지를 판단하는 과정이 있었는데, Nest.js를 이용하면 해당 과정을 편리하게 작업할 수 있어서 적어봅니다.

1. 에러 관련 파일 생성하기 📑

가장 먼저 에러 관련 파일들을 생성하겠습니다. 저는 src/exception 폴더 경로에 HttpError.ts라는 파일을 만든 다음, 에러를 던져주는 클래스를 만들어 주도록 하겠습니다. 에러를 던져주는 형식은 아래와 같습니다.

throw new HttpError(404, '존재하지 않는 사용자')

해당 클래스는 원래 nestjs/common에서 제공하는 HttpException 클래스를 사용하여 던져도 되지만, 저는 HttpException 클래스를 상속받아서 제가 원하는 방식으로 바꿔주었습니다.
(사실 별 차이는 없습니다 😀)

// HttpError.ts
import { HttpException } from "@nestjs/common";

export default class HttpError extends HttpException {
  public statusCode: number = 0;
  public message: string = '';

  constructor(status: number, message: string) {
    super(message, status);
    this.statusCode = status;
    this.message = message;
  }
}

이제 throw new HttpError(404, '존재하지 않는 사용자')와 같은 형식으로 에러를 생성하는것이 가능해졌습니다.

두번째로, CatchException.ts라는 파일을 만들어준 다음, 아래의 코드를 추가하였습니다.
해당 클래스는 전역으로 에러 필터를 걸어줄 때 필요로 하는 클래스이므로, 중요합니다.

// CatchException.ts
import { ArgumentsHost, Catch, ExceptionFilter, HttpException } from "@nestjs/common";
import { HttpArgumentsHost } from "@nestjs/common/interfaces";

@Catch()
export default class CatchException implements ExceptionFilter {
  // ExceptionFilter 인터페이스를 구현해야 하는 함수
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx: HttpArgumentsHost = host.switchToHttp();
    const response = ctx.getResponse();

    let httpError = null;
    console.log(exception);

    if (exception instanceof HttpException) {
      // status: XXX, message: 'XXX' 형식의 에러인지 판단합니다.
      httpError = {
        status: exception.getStatus(), // throw new HttpError()로 던진 첫번째 매개변수 status 값
        message: exception.message, // throw new HttpError()로 던진 두번째 매개변수 message 값
      };
    } 
    
    else {
      // XXXX() is not a function와 같은 서버 자체에서의 오류일때, 서버 오류로 처리합니다.
      httpError = {
        status: 500,
        message: '서버 오류입니다.',
      };
    }

    const { status, message } = httpError;
    // 클라이언트에게 응답을 넘겨줍니다. (위 조건분기에 따른 객체의 값들)
    return response.status(status).json({
      status,
      message,
    });
  }
}

2. app.module.ts 파일 수정 🐱‍👓

에러 클래스도 만들어 주었으니 이제 클래스를 전역 에러처리에 넣어주도록 하겠습니다. app.module.ts 파일을 열어준다음, providers 객체를 아래의 코드처럼 수정해줍니다.

import { APP_FILTER } from '@nestjs/core';
import CatchException from 'exception/CatchException';

// app.module.ts
@Module({
  imports: [],
  controllers: [],
  providers: [{
    provide: APP_FILTER,
    useClass: CatchException,
  }],
})
export class AppModule {}

이제 코드상으로 throw new HttpError() 형식의 오류를 던진다음, 정상적으로 에러가 출력되는지 확인하실 수 있습니다. 저같은 경우에는 자동으로 오류를 처리해주었으니, controller 파일들에서 쓰던
try / catch를 없애줄 수 있었어서 참 편리했던 것 같아요.

오늘은 이상으로 짧게 글을 마치도록 하겠습니다. 궁금한사항이 생기시면 댓글로 남겨주세요! 감사합니다.

profile
블로그 이전: https://yiyb-blog.vercel.app

0개의 댓글