상위 Epic
#728 에러 응답을 message 기반에서 code 기반으로 전환
왜
에픽 #728 은 클라의 에러 처리를 detail(사람이 읽는 메시지) 대신 안정적인 code 로 옮기는 것이 목표다. #739 가 인프라 + User 도메인만 이관해, 횡단(공통) 에러들은 아직 code=null 이다:
- Security 401 / 403 (
ApiResponseSecurityErrorHandlers)
- Bean Validation 400 (
@NotBlank · @Size 등)
- 표준 MVC 4xx (404 · 405 · 415 등 Spring 이 던지는 것)
- generic 500 (
handleUnexpected)
- 도메인 5xx (외부 의존성 실패 등)
이들은 전부 fail(category) 로만 내려가 code 가 비므로, 클라가 코드로 구분할 수 없다. 에픽의 궁극 목표(응답에서 detail 제거)를 완성하려면 공통 에러도 code 를 가져야 한다. 클라 전달용 매핑 문서는 별도로 정리했다 (4xx 는 구체 code, 5xx 는 재시도 방식별 3종).
무엇을
CommonErrorCode enum 신설
- 4xx 6종:
COMMON-UNAUTHORIZED(401) · COMMON-FORBIDDEN(403) · COMMON-NOT-FOUND(404) · COMMON-METHOD-NOT-ALLOWED(405) · COMMON-UNSUPPORTED-MEDIA-TYPE(415) · COMMON-INVALID-INPUT(400)
- 5xx 3종 (재시도 방식이 곧 code):
COMMON-RETRYABLE(502, 즉시 재시도) · COMMON-SERVER-BUSY(503, Retry-After 만큼 대기 후 재시도) · COMMON-SERVER-ERROR(500 · 502, 재시도 불가 - 백엔드가 고쳐야 함)
ErrorCodeCatalog 에 addAll(CommonErrorCode.entries) 등록
배선 (전부 fail(category) → fail(errorCode))
| 위치 |
대상 |
code |
ApiResponseSecurityErrorHandlers |
401 / 403 |
COMMON-UNAUTHORIZED / COMMON-FORBIDDEN |
GlobalExceptionHandler.handleIllegalArgument |
400 |
COMMON-INVALID-INPUT |
handleUnexpected |
500 |
COMMON-SERVER-ERROR |
handleExceptionInternal |
표준 MVC 4xx (400 / 404 / 405 / 415) |
해당 COMMON 4xx |
handleBaseException |
도메인 5xx |
category(RETRYABLE / SERVER_ERROR) → COMMON 5xx 로 뭉침 |
- 5xx 는 도메인별 code 를 두지 않고 재시도 방식별 3개로 뭉친다 - code 자체가 클라의 재시도 신호이므로.
문서 · 부수
- OpenAPI(
*Api · *ApiExamples) 공통 응답에 code 문서화
- 통합테스트에
$.code 단언 추가 (회귀 가드)
- (부수 정정)
ErrorCategory 의 RETRYABLE · SERVER_ERROR description 이 동일해 재시도 여부 오해를 주는 문구 정리
이 이슈 밖 (후속 분리)
- 503 SERVER-BUSY 실제 발생 - 서버 과부하 시 load shedding 으로 503 + Retry-After 를 내리는 구현은 별도 안정성 이슈. 이 이슈는 code 자리만 정의한다.
- 400 세분화 -
COMMON-INVALID-INPUT 하나로 통합 vs 검증 / 파싱 / 타입 분리는 클라 UX 합의 후 결정.
상위 Epic
#728 에러 응답을 message 기반에서 code 기반으로 전환
왜
에픽 #728 은 클라의 에러 처리를
detail(사람이 읽는 메시지) 대신 안정적인code로 옮기는 것이 목표다. #739 가 인프라 + User 도메인만 이관해, 횡단(공통) 에러들은 아직code=null이다:ApiResponseSecurityErrorHandlers)@NotBlank·@Size등)handleUnexpected)이들은 전부
fail(category)로만 내려가code가 비므로, 클라가 코드로 구분할 수 없다. 에픽의 궁극 목표(응답에서 detail 제거)를 완성하려면 공통 에러도 code 를 가져야 한다. 클라 전달용 매핑 문서는 별도로 정리했다 (4xx 는 구체 code, 5xx 는 재시도 방식별 3종).무엇을
CommonErrorCode enum 신설
COMMON-UNAUTHORIZED(401) ·COMMON-FORBIDDEN(403) ·COMMON-NOT-FOUND(404) ·COMMON-METHOD-NOT-ALLOWED(405) ·COMMON-UNSUPPORTED-MEDIA-TYPE(415) ·COMMON-INVALID-INPUT(400)COMMON-RETRYABLE(502, 즉시 재시도) ·COMMON-SERVER-BUSY(503, Retry-After 만큼 대기 후 재시도) ·COMMON-SERVER-ERROR(500 · 502, 재시도 불가 - 백엔드가 고쳐야 함)ErrorCodeCatalog에addAll(CommonErrorCode.entries)등록배선 (전부
fail(category)→fail(errorCode))ApiResponseSecurityErrorHandlersGlobalExceptionHandler.handleIllegalArgumenthandleUnexpectedhandleExceptionInternalhandleBaseException문서 · 부수
*Api·*ApiExamples) 공통 응답에 code 문서화$.code단언 추가 (회귀 가드)ErrorCategory의 RETRYABLE · SERVER_ERROR description 이 동일해 재시도 여부 오해를 주는 문구 정리이 이슈 밖 (후속 분리)
COMMON-INVALID-INPUT하나로 통합 vs 검증 / 파싱 / 타입 분리는 클라 UX 합의 후 결정.