기술과 산업/언어 및 프레임워크

NestJS 마스터 시리즈 9화. 예외 처리 전략 – 오류는 숨기지 말고 설계하라

B컷개발자 2025. 5. 4. 11:47
728x90

“서비스 품질은 에러 메시지를 보면 알 수 있다”

 

NestJS에서 예외 처리 시스템을 구조적으로 설계하는 방법을 다룹니다. HTTP 예외, ExceptionFilter, 커스텀 예외 클래스까지 실무 중심으로 예외 설계 전략을 소개합니다.

 


 

에러를 숨기는 백엔드는 신뢰할 수 없다

 

현업에서 발생하는 많은 장애는, 에러 그 자체보다 에러가 제대로 처리되지 않은 결과에서 시작된다.

NestJS는 @nestjs/common 모듈에 예외 처리 시스템을 내장하고 있으며, 이를 통해 통일된 에러 응답과 로깅 전략을 설계할 수 있다.

 


 

기본 예외 – HttpException 사용하기

 

NestJS는 HttpException 클래스를 통해 명시적인 에러 응답을 만들 수 있다.

import { HttpException, HttpStatus } from '@nestjs/common';

throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);

또는 객체 형태로 세부 메시지를 전달할 수 있다.

throw new HttpException(
  {
    status: HttpStatus.FORBIDDEN,
    error: 'You are not allowed to access this resource',
  },
  HttpStatus.FORBIDDEN,
);

 

 


 

커스텀 예외 클래스 만들기

 

자주 사용하는 예외는 클래스로 분리하면 가독성과 재사용성이 높아진다.

import { HttpException, HttpStatus } from '@nestjs/common';

export class UserNotFoundException extends HttpException {
  constructor(userId: string) {
    super(`User with ID ${userId} not found`, HttpStatus.NOT_FOUND);
  }
}

사용 예시:

if (!user) {
  throw new UserNotFoundException(id);
}

 

 


 

전역 예외 처리기 – ExceptionFilter

 

NestJS는 @Catch() 데코레이터를 사용한 예외 필터 시스템을 통해, 전역 또는 특정 예외에 대해 커스텀 응답 처리를 구현할 수 있다.

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

@Catch(HttpException)
export class HttpErrorFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const status = exception.getStatus();
    const message = exception.getResponse();

    response.status(status).json({
      statusCode: status,
      message,
      timestamp: new Date().toISOString(),
    });
  }
}

main.ts에서 전역 등록:

app.useGlobalFilters(new HttpErrorFilter());

 

 


 

비HTTP 예외도 처리 가능

 

NestJS는 @Catch()의 인자로 HTTP 외의 예외도 필터링할 수 있다.

@Catch(TypeError, QueryFailedError)

 

  • DB 예외, 타입 예외 등 다양한 상황에 맞는 전용 필터 구성 가능

 


 

로깅과 에러 응답을 분리하라

 

서비스가 성숙해질수록 에러 로깅클라이언트 응답은 분리되어야 한다.

 

  • 내부에는 스택 트레이스 포함한 상세 로그 저장
  • 외부에는 간결한 메시지와 statusCode만 전달

 

이런 전략은 LoggerExceptionFilter를 함께 사용하는 것으로 실현할 수 있다.

 


 

실무 적용 전략

전략내용

공통 예외 메시지 포맷 정의 statusCode, message, timestamp 등 일관된 구조
커스텀 예외 클래스 분리 도메인별로 예외 클래스를 정의해 로직과 구분
ExceptionFilter 계층화 HTTP 예외, DB 예외, 권한 예외 등 역할 분리
로깅 연계 Sentry, Logstash 등과 연동해 실시간 모니터링 구현

 

 


 

마무리 인사이트

 

NestJS는 예외 처리조차 설계 가능한 아키텍처 요소로 다룰 수 있도록 도와준다.

그냥 throw하는 것이 아니라, 의도적이고 예측 가능한 실패 흐름을 만들 수 있다는 것이 큰 장점이다.

 

  • 에러는 숨기지 말고, 구조화하라
  • 예외 메시지는 팀 내 API 계약의 일부다
  • 클라이언트, 백엔드, DevOps가 공유할 수 있는 언어로 설계해야 한다

 

좋은 서비스는 성공보다 실패를 잘 다루는 구조에서 시작된다

 


 

다음 회차 예고

 

NestJS 마스터 시리즈 10화. 미들웨어와 인터셉터 – 요청 흐름을 설계하는 법

요청 전/후 흐름 제어, 로깅, 인증, 응답 가공을 구조화하는 방법을 설명합니다.

 

728x90