[NestJS] TypeORM Error Handling

백엔드·2023년 8월 8일
0

NestJS

목록 보기
7/7

들어가며

NestJS와 TypeORM을 사용하여 API를 개발하던 중, 다양한 상황에서 발생할 수 있는 예외에 대한 처리가 필요했습니다. 다양한 예외 상황을 효과적으로 처리하기 위해 ErrorInterceptor를 활용해보았습니다.

이 글에서는 NestJS의 ErrorInterceptor를 사용하여 TypeORM 에러를 처리하는 방법에 대해 알아보겠습니다.

TypeORM 에러 처리의 어려움

TypeORM을 사용하다보면 데이터베이스 연결, 쿼리 실행, 트랜잭션 등에서 다양한 예외가 발생할 수 있습니다. 이러한 예외들은 데이터베이스 연결 문제, 쿼리 오류, 무결성 제약 조건 위반 등 다양한 상황에서 발생할 수 있으며, 각 예외들은 다른 방식으로 처리되어야 합니다. 따라서 이러한 예외들을 효과적으로 처리하기 위해서는 일일히 try-catch 문으로 처리하는 것보다는 중앙 집중화된 예외 처리 메커니즘이 필요합니다

ErrorInterceptor Example

ErrorInterceptor는 NestJS에서 예외 처리를 중앙에서 관리하고 효율적으로 처리할 수 있도록 도와주는 기능입니다. 모든 예외가 해당 인터셉터를 거쳐서 처리되기 때문에, 애플리케이션 전체에서 일관된 예외 처리를 구현할 수 있습니다.


@Injectable()
export class ErrorInterceptor implements NestInterceptor {
  constructor( // ...필요한 의존성 주입 ) {}

  private propagateException(err: any) { // [2]
    switch (true) {
      case err instanceof TypeORMError:
        throw new TypeORMException(// ... 필요한 생성자 인자 추가);
		
       // ... 다양한 case 추가
        
      default:
        break;
    }
  }

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    
    return next.handle().pipe(
      catchError((err) => {
        const returnObj: Record<string, any> = {
          message: err.message,
        };

       	// ... returnObj에 debug에 필요한 속성들 추가
        	
        
        if (err instanceof HttpException) // [1] {
         
         // ... HttpException 관련 error handling 
          
        }

        context
          .switchToHttp()
          .getResponse()
          .status(HttpStatus.INTERNAL_SERVER_ERROR);

        this.propagateException(err, returnObj); // propagate error for exception filters
        return of(returnObj);
      }),
    );
  }
}

[1]: if (err instanceof HttpException) { ... }

해당 조건문을 통해 TypeORM 에러와 일반적인 HTTP 예외를 구분하여 처리합니다
일반적인 HTTP 예외일 경우 해당 조건문에서 HttpException 관련 error handling 로직을 추가하면 됩니다.

[2]: private propagateException(err: any) { ... }

propagateException method는 TypeORMError 관련 예외 처리를 담당합니다.
TypeORMError 관련 에러 일 경우 TypeORMException을 던집니다.

TypeORMException은 GeneralException 클래스를 상속받고, GeneralException은 HttpException 클래스를 상속받고 있습니다.

TypeORMException, GeneralException을 구현함으로써 특정 상황에서 발생하는 TypeORM 예외를 더 많은 정보와 함께 노출할 수 있어 TypeORMError를 보다 구체적으로 처리할 수 있습니다.

GeneralException example

export class GeneralException extends HttpException {
  private readonly _callClass: string;
  private readonly _callMethod: string;

  constructor(
    // 디버깅에 필요한 속성 정의
  ) {
    
    // ....
    super(response, status || HttpStatus.INTERNAL_SERVER_ERROR);
   
    
  }

 // 디버깅에 필요한 속성 get method 정의

	
}

GeneralException 클래스는 NestJS에서 HTTP 응답과 관련된 예외를 처리하기 위해 확장된 클래스입니다. 생성자에서 호출된 super()를 통해 HTTP 응답에 필요한 정보를 포함하는 response 객체와 상태 코드를 지정하여 예외 객체를 생성합니다.

또한, 사용자 정의 프로퍼티를 추가하여 디버깅에 필요한 속성을 정의할 수 있습니다.

TypeORMException example

export class TypeORMException extends GeneralException {
  private readonly _originalError: TypeORMError;

  constructor(// 디버깅에 필요한 속성 정의) {
    super(// 필요한 생성자 인수 주입);
    
  }
	
  // 디버깅에 필요한 속성 get method 정의
}

TypeORMException 클래스는 GeneralException 클래스를 상속받습니다. 해당 클래스는 TypeORM과 관련된 예외를 처리하기 위해 구현된 클래스입니다. 생성자에서는 super()를 호출하여 GeneralException의 생성자를 실행합니다.

예를 들어, TypeORM에서 발생한 에러 객체(TypeORMError)의 메시지와 스택 트레이스를 GeneralException의 생성자에 전달하여 예외 객체를 생성할 수 있습니다.

또한, 필요에 따라 사용자 정의 프로퍼티를 추가하여 원본 TypeORM 에러 객체를 보관하고, get error() 메서드를 통해 원본 에러 객체에 접근하는 로직을 추가할 수 있습니다.

이렇게 구현된 TypeORMException 클래스를 사용하면, TypeORM과 관련된 예외가 발생했을 때 GeneralException의 기능을 이용하여 예외를 처리할 수 있습니다.

이를 통해 NestJS 애플리케이션에서 TypeORM과 관련된 예외를 효과적으로 처리하고, 디버깅에 유용한 정보를 포함한 예외 응답을 클라이언트에게 제공할 수 있습니다.

TypeORMExceptionFilter example

@Catch(TypeORMException)
export class TypeORMExceptionFilter implements ExceptionFilter {
  catch(exception: TypeORMException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();

    let responseStatus = HttpStatus.INTERNAL_SERVER_ERROR;
    const responseJson: Record<string, any> = { // TypeORMException에 정의된 정보를 통해 구현 };

   
    return response.status(responseStatus).json(responseJson);
  }
}

위의 코드는 TypeORMException 클래스를 처리하는 NestJS의 예외 필터인 TypeORMExceptionFilter 입니다. @Catch(TypeORMException) 데코레이터를 사용하여 TypeORMException 클래스로부터 발생한 예외를 처리합니다.

예외 필터에서는 TypeORMException 객체에서 정의된 정보를 가져와서 JSON 응답에 포함합니다. .

결과적으로, TypeORMExceptionFilter는 TypeORM과 관련된 예외가 발생했을 때 해당 예외의 정보를 JSON 형태로 클라이언트에게 반환합니다. 이를 통해 클라이언트는 발생한 예외에 대한 정보를 쉽게 확인할 수 있으며, 개발 환경에서는 추가적인 디버깅 정보를 제공받을 수 있습니다.

결론

NestJS에서 TypeORM 에러를 효과적으로 처리하기 위해 ErrorInterceptor를 활용해보았습니다. ErrorInterceptor를 통해 애플리케이션 전체에서 일관된 예외 처리를 구현하고, TypeORM 예외를 TypeORMException 예외 객체로 변환하였습니다.

TypeORMExceptionFilter는 TypeORMException 예외를 처리하여 응답 형식을 제어함으로써 발생한 예외에 대한 정보를 클라이언트에서 쉽게 확인할 수 있으며, 개발 환경에서는 추가적인 디버깅 정보를 제공받을 수 있습니다.

profile
백엔드 개발자

0개의 댓글