에러코드 설계 벤치마킹 & NestJS에서 에러 응답 커스텀 방법
문제상황
- Nest.js에서 기본 에러 응답 형식은 위와 같습니다. 이렇게 응답을 주면 협업에 어려움이 있을 것 같습니다.
- 일단 에러가 어느 API에서 발생했는지, 언제 발생했는지 알기 어렵습니다.
- 하나의 상태 코드에 대해서도 세부적으로 분류하기 위한 에러 코드도 필요해보입니다.
벤치마킹
다른 기업들에서는 어떤 에러 코드 체계를 가지고 운영 중인지 살펴보겠습니다.
1. NAVER WORKS Developers
- 링크 : https://developers.worksmobile.com/kr/docs/error-codes
- HTTP 상태 코드와 별도의 에러 코드 체계를 가지고, 해당 코드를 응답 본문에 포함시켜주고 있습니다.
- 동일한 상태 코드에 대해서 여러 종류의 에러 코드를 지정해놓았다는 점에서 어떤 에러인지 파악하기 쉬워서 좋았습니다.
2. Kakao Developers
- 링크 : https://developers.kakao.com/docs/latest/ko/rest-api/reference#response-code
- 마찬가지로 HTTP 상태코드와 별개로 내부적인 에러 코드 체계를 가지고 있습니다.
- code와 msg를 포함하여 에러 응답을 보내주고 있습니다.
3. Line Developers
- 링크 : https://developers.line.biz/en/reference/messaging-api/#error-responses
- 라인도 마찬가지로 내부적인 에러코드(error)가 있고, 에러에 대한 설명을 함께 본문에 담아서 보내줍니다.
- details에서 에러가 발생한 구체적인 프로퍼티를 명시해준 점이 좋았습니다.
벤치마킹 결과
세 기업의 응답 형식을 살펴보고 다른 기술 블로그들을 살펴본 결과, NestJS 기본 에러 응답 형식에서 보완해야 할 점은 다음과 같습니다.
- 자체 에러 코드( =/= HTTP 상태코드)
- 에러에 대한 설명
- 에러 발생 위치
- 에러 발생 시간
NestJS에서 에러 응답 커스텀하기
목표
저의 목표는 에러 응답을 아래와 같이 설계하는 것입니다.
기존에 있던 statusCode는 HTTP 요청 라이브러리(fetch, axios 같은...)에서 HTTP 응답을 추상화하여 접근할 수 있는 방법을 제공하기 때문에 삭제했습니다.
이 정도면 협업 중 문제 발생시 응답 본문만 캡처해서 공유해준다면 문제 파악에 어려움은 없을 거라고 생각이 들었습니다.
{
"path": "/auth/sign-in",
"errorCode": "USER_PASSWORD_IS_WRONG",
"detail": "비밀번호가 일치하지 않습니다.",
"timestamp": "2024-07-31T17:42:40.585Z"
}
과정
1. ErrorCode enum을 정의했습니다.
그리고 ErrorCode를 key, 에러 메세지를 value로 하는 Record 타입의 ErrorMessage 정의했습니다.
이렇게 한 이유는 에러 코드와 메세지를 하나씩 매칭하고, 에러 코드를 가지고 메세지를 불러와서 사용하기 위함이었습니다.
2. ErrorCode를 사용하여 비즈니스 로직을 작성합니다.
Exception 생성시 ErrorCode를 인자로 넣어줍니다.
3. 기본 에러 응답을 커스텀 해주기 위해 filter를 만들었습니다.
Exception의 객체의 response의 message에 ErrorCode가 담겨있는데, 타입이 따로 제공되지 않아서 인터페이스를 만들었습니다.
응답 형태를 커스텀 해주는 로직을 포함하였고, 이 필터를 글로벌 필터로 등록해주었습니다.
결과
- 좋은 에러 코드 설계는 시스템의 유지보수성과 협업 시 사용자 경험 측면에서 중요하다고 생각합니다.
- 1) 일관성, 2) 의미가 있고 이해하기 쉬운 메세지, 3) 명확한 분류체계 가 가장 중요하다는 생각이 들었습니다.
TODO
- i18n 라이브러리 같은 것을 활용해 다국어 처리도 지원해보면 좋을 것 같습니다.
- 로깅 시스템에서 조회할 수 있도록 trace id를 담을 수도 있다고 합니다. [참고]
참고
1. https://developers.worksmobile.com/kr/docs/error-codes
2. https://developers.kakao.com/docs/latest/ko/rest-api/reference#response-code
3. https://developers.line.biz/en/reference/messaging-api/#error-responses