프로젝트가 조금씩 진행되어 질 때 마다, 코드의 양이 많아 질 때마다, 다루는 데이터가 많아 질 때 마다, 서버는 최대한 견고하게 작동해야 하며, 그 응답도 통일성이 있어야 한다고 생각한다.
응답은 물론, 우리의 소망과는 별개로 오류는 어디서든 항상 존재 할 수 있으며, 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
}
하지만, NestJS의 기능 중에 다음과 같은 기능이 존재한다.
export class SomethingDto {
@IsNotEmpty()
field : number
}
를 사용한 Validation과,
throw new UnauthorizedException(object, 'description');
과 같은 NestJS 가 지원하는 HttpException 이다.
위와 같은 기능을 사용하면서 NestJS 가 자동적으로 던지는 응답(에러)객체는 다음과 같다
{
"statusCode" : HttpStatusCode,
"message" : string[],
"error" : string
}
따라서 프로젝트에서 사용하는 형식으로 응답 객체를 바꾸어 주어야 한다.
이때 사용한 것이 예외 처리 레이어를 두는 방식이며, 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);
}
이렇게 작성한 이후 main.ts 에서 다음과 같이 사용했다.
// 중략
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(8080);
// 후략
이렇게 했더니 다음과 같이 시스템에서 던진 에러메세지가 잘 변형되어 내려왔다.
나와 같이 헤메이는 초보자에게 힘이 되었으면 좋겠다.
Reference
Top comments (0)