| 1 | package com.project.auth.presentation.support.exception; | |
| 2 | ||
| 3 | import com.project.auth.application.support.exception.ClientFacingErrorCode; | |
| 4 | ||
| 5 | /** | |
| 6 | * 클라이언트에 반환되는 presentation 계층 에러 코드. | |
| 7 | * | |
| 8 | * 클라이언트 SDK가 원인별로 분기 로직을 짤 수 있도록 트리거별로 의도적으로 코드를 분리했다. | |
| 9 | * <ul> | |
| 10 | * <li>{@link #INVALID_INPUT} — 요청 본문 빈 검증 실패 | |
| 11 | * ({@code @Valid @RequestBody}, MethodArgumentNotValidException).</li> | |
| 12 | * <li>{@link #INVALID_REQUEST_BODY} — 요청 본문 파싱 실패 | |
| 13 | * (HttpMessageNotReadableException, 예: 잘못된 JSON).</li> | |
| 14 | * <li>{@link #MISSING_PARAMETER} — 필수 query/form 파라미터 누락 | |
| 15 | * (MissingServletRequestParameterException).</li> | |
| 16 | * <li>{@link #CONSTRAINT_VIOLATION} — 컨트롤러 메서드 인자 범위 밖에서 트리거된 | |
| 17 | * Jakarta Bean Validation (ConstraintViolationException, 주로 @Validated 서비스 | |
| 18 | * 또는 @RequestParam 제약).</li> | |
| 19 | * <li>{@link #TYPE_MISMATCH} — query/path/form 값을 대상 타입으로 변환 실패 | |
| 20 | * (TypeMismatchException, 예: Long에 {@code id=abc}).</li> | |
| 21 | * <li>{@link #INVALID_PARAMETER} — 핸들러 메서드 레벨 검증 실패 | |
| 22 | * (HandlerMethodValidationException, 예: {@code @RequestParam @Size}).</li> | |
| 23 | * <li>{@link #MISSING_HEADER} — 필수 @RequestHeader 누락.</li> | |
| 24 | * <li>{@link #REQUEST_BINDING_FAILED} — 더 구체적인 코드로 분류되지 않은 | |
| 25 | * 일반 ServletRequestBindingException.</li> | |
| 26 | * <li>{@link #METHOD_NOT_ALLOWED} — 라우트가 지원하지 않는 HTTP 메서드.</li> | |
| 27 | * <li>{@link #RESOURCE_NOT_FOUND} — 요청 경로에 매칭되는 라우트/정적 리소스 없음.</li> | |
| 28 | * <li>{@link #UNSUPPORTED_MEDIA_TYPE} — 라우트가 수용하지 않는 Content-Type.</li> | |
| 29 | * <li>{@link #NOT_ACCEPTABLE} — Accept 헤더를 만족시킬 수 없음.</li> | |
| 30 | * <li>{@link #PAYLOAD_TOO_LARGE} — multipart 업로드가 허용 한도 초과.</li> | |
| 31 | * <li>{@link #MESSAGE_NOT_WRITABLE} — 응답 직렬화 실패 (5xx).</li> | |
| 32 | * <li>{@link #UNHANDLED_CLIENT_ERROR} — 더 구체적인 매핑이 없는 4xx 상태 캐리어 | |
| 33 | * (ResponseStatusException, ErrorResponseException) 또는 컨테이너 레벨 4xx 응답에 | |
| 34 | * 대한 폴백.</li> | |
| 35 | * </ul> | |
| 36 | */ | |
| 37 | public enum PresentationErrorCode implements ClientFacingErrorCode { | |
| 38 | INVALID_INPUT("PRES-001", "요청 값이 올바르지 않습니다."), | |
| 39 | INVALID_REQUEST_BODY("PRES-002", "요청 본문을 읽을 수 없습니다."), | |
| 40 | METHOD_NOT_ALLOWED("PRES-003", "지원하지 않는 HTTP 메서드입니다."), | |
| 41 | MISSING_PARAMETER("PRES-004", "필수 요청 파라미터가 누락되었습니다."), | |
| 42 | RESOURCE_NOT_FOUND("PRES-005", "요청한 리소스를 찾을 수 없습니다."), | |
| 43 | CONSTRAINT_VIOLATION("PRES-006", "요청 값이 제약 조건을 위반했습니다."), | |
| 44 | UNSUPPORTED_MEDIA_TYPE("PRES-007", "지원하지 않는 Content-Type입니다."), | |
| 45 | NOT_ACCEPTABLE("PRES-008", "요청한 응답 형식을 제공할 수 없습니다."), | |
| 46 | MISSING_HEADER("PRES-009", "필수 요청 헤더가 누락되었습니다."), | |
| 47 | REQUEST_BINDING_FAILED("PRES-010", "요청 바인딩에 실패했습니다."), | |
| 48 | MESSAGE_NOT_WRITABLE("PRES-011", "응답 데이터를 처리할 수 없습니다."), | |
| 49 | PAYLOAD_TOO_LARGE("PRES-012", "요청 본문 크기가 허용 한도를 초과했습니다."), | |
| 50 | UNHANDLED_CLIENT_ERROR("PRES-013", "처리하지 못한 클라이언트 오류입니다."), | |
| 51 | TYPE_MISMATCH("PRES-014", "요청 파라미터 타입이 올바르지 않습니다."), | |
| 52 | INVALID_PARAMETER("PRES-015", "요청 파라미터 검증에 실패했습니다."); | |
| 53 | ||
| 54 | private final String code; | |
| 55 | private final String message; | |
| 56 | ||
| 57 | PresentationErrorCode(String code, String message) { | |
| 58 | this.code = code; | |
| 59 | this.message = message; | |
| 60 | } | |
| 61 | ||
| 62 | @Override | |
| 63 | public String code() { | |
| 64 |
1
1. code : replaced return value with "" for com/project/auth/presentation/support/exception/PresentationErrorCode::code → NO_COVERAGE |
return code; |
| 65 | } | |
| 66 | ||
| 67 | @Override | |
| 68 | public String message() { | |
| 69 |
1
1. message : replaced return value with "" for com/project/auth/presentation/support/exception/PresentationErrorCode::message → NO_COVERAGE |
return message; |
| 70 | } | |
| 71 | } | |
Mutations | ||
| 64 |
1.1 |
|
| 69 |
1.1 |