DEV Community

Vincent Jang
Vincent Jang

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)