DEV Community

Phantola
Phantola

Posted on

How to customize HTTP Exception In NestJS

프로젝트가 조금씩 진행되어 질 때 마다, 코드의 양이 많아 질 때마다, 다루는 데이터가 많아 질 때 마다, 서버는 최대한 견고하게 작동해야 하며, 그 응답도 통일성이 있어야 한다고 생각한다.

응답은 물론, 우리의 소망과는 별개로 오류는 어디서든 항상 존재 할 수 있으며, Front-end 에서 응답과 오류를 잘 가공하여 로직을 처리하려면, 서버에서는 항상 통일된 형태의 객체로 응답/오류를 전해주어야 한다.

현재 진행중인 프로젝트에서는 다음과 같은 응답 객체 양식을 지켜주고 있다. 에러가 난다면 다음과 같은 형식으로 내려준다.

{
  "status" : 401, // Http Status Code
  "code" : "UNAUTHORIZED_USER" // string Response code
  "error" : true // is error occurred?
  "message" : "권한이 없습니다." // message for request,
  "data" : // response data, original error object
}
Enter fullscreen mode Exit fullscreen mode

하지만, NestJS의 기능 중에 다음과 같은 기능이 존재한다.

export class SomethingDto {
  @IsNotEmpty()
  field : number
}
Enter fullscreen mode Exit fullscreen mode

를 사용한 Validation과,

throw new UnauthorizedException(object, 'description');
Enter fullscreen mode Exit fullscreen mode

과 같은 NestJS 가 지원하는 HttpException 이다.

위와 같은 기능을 사용하면서 NestJS 가 자동적으로 던지는 응답(에러)객체는 다음과 같다

{
  "statusCode" : HttpStatusCode,
  "message" : string[],
  "error" : string
}
Enter fullscreen mode Exit fullscreen mode

따라서 프로젝트에서 사용하는 형식으로 응답 객체를 바꾸어 주어야 한다.

이때 사용한 것이 예외 처리 레이어를 두는 방식이며, Filter 를 사용한다. 다음은 내가 사용한 방식이다.
피드백이 있다면 언제든 부족한 점을 알려주면 감사드린다.

  • http-exception.filter.ts
@Catch()
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: Error, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const res = ctx.getResponse<Response>();
    const req = ctx.getRequest<Request>();
  }

    if(!(exception instanceof HttpException)) {
      exception = new HttpException(new ResponseDto(~~),     
      HttpStatus.Internal_Server_Error);
    }

    let response = (exception as HttpException).getResponse();

    // 시스템이 자동으로 던진 에러에는 statusCode가 존재함.
    if(response['statusCode']) {
      // your transform response object
    }

    const log = {
      timeStamp: new Date();
      url: req.url;
      response
    };

    Logger.error(long)

    res.status((exception as 
    HttpException).getStatus()).json(response);
}
Enter fullscreen mode Exit fullscreen mode

이렇게 작성한 이후 main.ts 에서 다음과 같이 사용했다.

// 중략

app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(8080);

// 후략
Enter fullscreen mode Exit fullscreen mode

이렇게 했더니 다음과 같이 시스템에서 던진 에러메세지가 잘 변형되어 내려왔다.

Image description

나와 같이 헤메이는 초보자에게 힘이 되었으면 좋겠다.

Reference

Top comments (0)