이전 글에서 예외 처리 구조를 정리하면서
ErrorCode를 Enum으로 관리하는 방식을 사용했다.
근데 막상 적용해보니까 느낀 건 하나였다.
👉 단순히 enum으로 만드는 게 중요한 게 아니라
👉 “에러 코드를 어떻게 설계할 것인가”가 더 중요했다.
왜 에러 코드가 필요할까?
처음에는 그냥 메시지만 내려줘도 된다고 생각했다.
{
"message":"유저를 찾을 수 없습니다."
}
하지만 이 방식에는 분명한 문제가 있었다.
- 프론트에서 문자열로 분기해야 한다 (비효율)
- 메시지가 바뀌면 로직도 같이 깨진다
- 어떤 종류의 에러인지 명확하지 않다
특히 협업하면서 느낀 건
👉 “메시지는 사람이 보는 용도고, 로직은 코드로 처리해야 한다” 는 점이었다.
그래서 단순 메시지가 아니라
👉 코드 기반으로 에러를 구분해야겠다고 생각했다.
내가 고민했던 설계 기준
에러 코드를 설계하면서 몇 가지 기준을 세웠다.
1. 도메인 단위로 나누기
USER_001
POST_003
CATEGORY_004
이렇게 도메인 prefix를 붙였다.
→ 이유
- 어디서 발생한 에러인지 바로 알 수 있고
- 도메인별로 관리하기 쉬워진다
👉 나중에 에러가 많아져도 정리가 잘 된다.
2. HTTP 상태코드와 함께 관리
USER_NOT_FOUND(404,"USER_001","유저를 찾을 수 없습니다.")
단순히 코드만 있는 게 아니라
- 상태코드
- 에러 코드
- 메시지
를 하나로 묶어서 관리했다.
이렇게 하니까
👉 예외 하나만으로 응답 전체를 구성할 수 있게 됐다.
3. 에러 유형을 명확하게 구분하기
상태코드를 대충 쓰지 않고 기준을 정했다.
- 400 → 잘못된 요청 (validation, 입력값)
- 401 / 403 → 인증 / 권한 문제
- 404 → 리소스 없음
- 409 → 중복, 충돌
예를 들어
DUPLICATED_EMAIL(409, "USER_004", "이미 사용 중인 이메일입니다.")
👉 “중복”을 400으로 처리할 수도 있었지만
→ **의미적으로 더 맞는 409(CONFLICT)**로 분리했다.
이렇게 기준을 잡아두니까
나중에 에러를 추가할 때도 고민이 줄어들었다.
4. Validation 에러는 따로 처리
Validation은 일반 예외와 다르게 처리했다.
이유는 하나였다.
👉 어떤 필드에서 문제가 발생했는지 알려줘야 하기 때문
그래서 응답에 field를 포함시켰다.
{
"status":400,
"message":"제목은 공백일 수 없습니다.",
"field":"title"
}
이걸 적용하고 나서
👉 프론트에서 에러 위치를 바로 표시할 수 있게 됐고
👉 UX도 훨씬 좋아졌다.
설계하면서 느낀 점
처음에는
👉 “에러 코드까지 이렇게 나눠야 하나?” 싶었는데
막상 적용해보니까 완전히 달랐다.
- 에러가 훨씬 명확해졌고
- 프론트와의 소통이 쉬워졌고
- 유지보수가 훨씬 편해졌다
정리
이번에 ErrorCode를 설계하면서 느낀 건 하나였다.
👉 에러 코드는 단순한 값이 아니라, API와 프론트 사이의 약속이다.