Nest.js를 배워보자/10. NestJS에서 REST API 베스트 프랙티스

NestJS REST API 에러 핸들링 베스트 프랙티스

_Blue_Sky_ 2025. 12. 3. 09:59
728x90

NestJS에서 REST API의 에러 핸들링은 일관적이고 예측 가능한 방식으로 클라이언트에게 오류 정보를 제공하는 데 초점을 맞춥니다.

1. 전역 예외 필터 (Global Exception Filter) 활용

NestJS의 Exception Filter를 사용하여 모든 애플리케이션 레벨의 예외를 중앙 집중식으로 처리하는 것이 가장 중요합니다.

  • 목표: 모든 예외 응답의 형식을 통일하고, 에러 로깅 등의 공통 작업을 한 곳에서 처리합니다.
  • 구현: main.ts 또는 app.module.ts에서 전역으로 등록하여 Controller 계층 밖에서 발생하는 모든 예외를 잡아 처리합니다. 
// main.ts 또는 app.module.ts
// 모든 예외를 처리할 AllExceptionsFilter를 전역으로 등록
app.useGlobalFilters(new AllExceptionsFilter(app.get(HttpAdapterHost)));

2. 내장 HttpException 및 서브 클래스 사용

Business Logic 내부에서 에러가 발생했을 때, NestJS가 제공하는 표준 예외 클래스를 던져야 합니다. 이는 프레임워크가 정의한 표준 예외 객체를 사용함으로써 일관된 HTTP 상태 코드를 보장합니다.

  • HttpException: 사용자 정의 에러 메시지와 HTTP 상태 코드를 포함하는 기본 클래스입니다.
  • 서브 클래스 활용: NotFoundException (404), BadRequestException (400), UnauthorizedException (401) 등 이미 정의된 서브 클래스를 사용하면 코드가 더욱 명시적이고 깔끔해집니다.
// Service 내부 예시
import { NotFoundException } from '@nestjs/common';

if (!user) {
    // 404 상태 코드로 응답하도록 자동으로 변환됨
    throw new NotFoundException('사용자를 찾을 수 없습니다.'); 
}

3. 사용자 정의 예외 클래스 (Custom Exception Class)

내장된 HttpException으로 표현하기 어려운 복잡하거나 도메인 특화된 에러 (예: 잔액 부족, 중복 이메일)의 경우, 사용자 정의 예외 클래스를 만들어 사용합니다.

  • 목표: 에러를 던지는 지점에서 비즈니스 의미를 명확하게 전달하며, 응답 시 내부 에러 코드를 포함하도록 설계할 수 있습니다.
  • 구현: 기본 HttpException을 상속받아 정의합니다.
// email-conflict.exception.ts
import { HttpException, HttpStatus } from '@nestjs/common';

export class EmailConflictException extends HttpException {
    constructor() {
        // 409 Conflict 상태 코드를 사용
        super('이미 존재하는 이메일입니다.', HttpStatus.CONFLICT); 
    }
}

4. 일관된 에러 응답 형식 통일 (Standardized Error Response)

클라이언트가 에러 응답을 쉽게 파싱할 수 있도록 전역 예외 필터를 통해 응답 구조를 표준화해야 합니다.

필드 타입 설명
statusCode Number HTTP 상태 코드 (예: 404, 500)
path String 요청 경로
timestamp String 에러 발생 시간
message String 사용자에게 보여줄 에러 설명
errorCode String (선택) 내부 비즈니스 에러 코드
 
{
  "statusCode": 404,
  "timestamp": "2025-12-03T00:54:51.000Z",
  "path": "/users/999",
  "message": "사용자를 찾을 수 없습니다."
}

 

728x90