2025-12-23

오늘 배운 것

IllegalArgumentException은 항상 400일까?

오늘의 질문

  • IllegalArgumentException을 400 Bad Request로 매핑하는 것이 정말 안전한가?

핵심 개념 정리

1. 4xx vs 5xx의 본질적 차이

  • 4xx (Client Error)
    • 클라이언트 요청 자체가 잘못됨
    • 요청을 수정하지 않으면 재시도 의미 없음
    • 예: 400, 401, 404
  • 5xx (Server Error)
    • 서버 내부 문제로 처리 실패
    • 일시적 장애 가능 → 재시도(backoff) 의미 있음
    • 예: 500, 502, 503
  • 기준은 단순함

    책임이 클라이언트인가, 서버인가


2. 운영·모니터링 관점에서의 중요성

  • 5xx는 즉시 알람·대응 대상
  • 서버 버그를 4xx로 내려버리면
    • 클라이언트 문제로 오인
    • 장애 인지 및 대응 지연
  • 반대로 클라이언트 오류를 5xx로 주면
    • 불필요한 장애 알람 증가
    • 진짜 장애를 놓칠 위험

IllegalArgumentException이 위험한 이유

  • IllegalArgumentException은 의미가 너무 넓은 예외
    • 클라이언트 입력 오류
    • 서버 내부 로직 오류
    • 라이브러리/프레임워크 내부 오류
  • 발생 원인이 외부 요청인지 내부 버그인지 구분 불가

예시

  • Thread.setPriority(1~10 범위 초과 시 IllegalArgumentException 발생)
  • 서버 내부 계산 로직 오류로도 충분히 발생 가능
  • 이걸 400으로 내려버리면
    • 서버 버그가 클라이언트 잘못으로 숨겨짐

권장되는 예외 매핑 전략

1. 기본 원칙

  • 예상 못 한 예외 → 5xx
  • 명백한 클라이언트 잘못 → 4xx
  • 원인을 파악한 뒤 4xx로 좁혀가는 방식이 안전

2. 비즈니스 예외 vs 시스템 예외

  • 비즈니스 예외
    • 입력 조건 불만족, 정책 위반 등
    • 예: 최소 주문 금액 미달
    • → 400 Bad Request
  • 시스템 예외
    • DB 장애, 외부 API 실패, NPE, 내부 로직 버그
    • → 5xx
  • 예측 가능한 시스템 예외
    • fallback, 별도 모니터링 포인트로 관리

3. 커스텀 예외 사용

  • IllegalArgumentException 대신
    • BusinessException
    • InvalidExpressionException 등
  • 의도적으로 400을 내려야 하는 경우에만 사용
  • Global Exception Handler에서는
    • BusinessException만 400으로 매핑
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)

출처

https://techblog.woowahan.com/21686/

results matching ""

    No results matching ""