IT이야기

nestjs 오류 처리 접근법(비즈니스 논리 오류 대 http 오류)이란 무엇인가?

cyworld 2022. 3. 16. 22:08
반응형

nestjs 오류 처리 접근법(비즈니스 논리 오류 대 http 오류)이란 무엇인가?

네스트JS를 사용하여 API를 만드는 동안 오류/예외를 처리하는 가장 좋은 방법이 무엇인지 궁금했다.나는 두 가지 다른 접근법을 발견했다.

  1. 개별 서비스 및 검증 파이프 보유throw new Error()에 제어 장치가 있음catch그런 다음 적절한 종류의 것을 던진다.HttpException(BadRequestException,ForbiddenException등등)
  2. 컨트롤러에게 단순히 해당 비즈니스 로직의 처리를 담당하는 서비스/유효성 확인 파이프 방법을 호출하고 적절한 방법을 제공하도록 하십시오.HttpException.

두 가지 접근법 모두 장단점이 있다.

  1. 이 방법이 옳은 것 같지만, 서비스는 돌아올 수 있다.Error여러 가지 이유로, 해당 종류의 컨트롤러를 통해 어떻게 알 수 있는가?HttpException돌아올까?
  2. 매우 유연하지만Http서비스에 관련된 것들은 잘못된 것 같다.

궁금했는데, 어떤 게 "둥지 js"의 방법일까?

이 일을 어떻게 처리하시겠습니까?

당신의 비즈니스 논리가 실패했다고 가정해 봅시다.EntityNotFoundError그리고 당신은 그것을 에 매핑하기를 원한다.NotFoundException.

이를 위해 오류를 변환하는 를 만들 수 있다.

@Injectable()
export class NotFoundInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    // next.handle() is an Observable of the controller's result value
    return next.handle()
      .pipe(catchError(error => {
        if (error instanceof EntityNotFoundError) {
          throw new NotFoundException(error.message);
        } else {
          throw error;
        }
      }));
  }
}

그런 다음 추가해서 사용할 수 있다.@UseInterceptors(NotFoundInterceptor)제어기의 클래스 또는 방법에 따라, 또는 심지어 모든 경로에 대한 글로벌 인터셉터로서.물론 하나의 인터셉터에 여러 개의 오류를 매핑할 수도 있다.

코드와 상자에 넣어봐.

Nest Js는 애플리케이션 계층에서 처리되지 않은 오류를 처리하는 예외 필터를 제공하므로, Http가 아닌 예외에 대해 500개의 내부 서버 오류를 반환하도록 수정했다.그런 다음 서버에 예외를 기록하면 무엇이 잘못되었는지 알고 수정할 수 있다.

import 'dotenv/config';
import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common';

@Catch()
export class HttpErrorFilter implements ExceptionFilter {
  private readonly logger : Logger 
  constructor(){
    this.logger = new Logger 
  }
  catch(exception: Error, host: ArgumentsHost): any {
    const ctx = host.switchToHttp();
    const request = ctx.getRequest();
    const response = ctx.getResponse();

    const statusCode = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR
    const message = exception instanceof HttpException ?  exception.message || exception.message?.error: 'Internal server error'

    const devErrorResponse: any = {
      statusCode,
      timestamp: new Date().toISOString(),
      path: request.url,
      method: request.method,
      errorName: exception?.name,
      message: exception?.message
    };

    const prodErrorResponse: any = {
      statusCode,
      message
    };
    this.logger.log( `request method: ${request.method} request url${request.url}`, JSON.stringify(devErrorResponse));
    response.status(statusCode).json( process.env.NODE_ENV === 'development'? devErrorResponse: prodErrorResponse);
  }
}

HTTP 인터페이스뿐만 아니라 GraphQL 또는 다른 인터페이스에 대해서도 서비스를 바인딩하십시오.따라서 서비스에서 비즈니스 로직 레벨 예외를 HTTP 레벨 예외(BadRequest)로 캐스트하는 것이 좋다.컨트롤러의 예외, ForbedException)

가장 간단한 방법으로는

import { BadRequestException, Injectable } from '@nestjs/common';

@Injectable()
export class HttpHelperService {
  async transformExceptions(action: Promise<any>): Promise<any> {
    try {
      return await action;
    } catch (error) {
      if (error.name === 'QueryFailedError') {
        if (/^duplicate key value violates unique constraint/.test(error.message)) {
          throw new BadRequestException(error.detail);
        } else if (/violates foreign key constraint/.test(error.message)) {
          throw new BadRequestException(error.detail);
        } else {
          throw error;
        }
      } else {
        throw error;
      }
    }
  }
}

그 다음에

참조URL: https://stackoverflow.com/questions/51112952/what-is-the-nestjs-error-handling-approach-business-logic-error-vs-http-error

반응형