불친절한 400 응답에서 벗어나기 ( Valid )

KUN·2025년 6월 12일

문제 인식 및 정의

이 화면을 보고, 진짜 문제를 짚어보자.
지금 이 응답은 400 Bad Request를 던졌는데,
과연 이메일 형식이 잘못된 걸까?
아니면 비밀번호가 누락된 걸까?

사용자 입장에서 보면, 무엇이 잘못됐는지 알 수 있는 방법전혀 없다.


이곳 말고도 여러곳의 Controller 에서 같은 @Vaild 를 던지지만 예외처리는 전혀 처리 되지않았다.

콘솔에 뜨는 걸 사용자는 알 수 없다.

정의

입력값 유효성 검사가 실패해도,
서버는 구체적인 필드 오류 메시지를 응답하지 않고,
단순히 400 에러만 던진다.

이로 인해 사용자는 문제를 수정하지 못하고,
서비스 이용 흐름이 끊기게 된다.

즉 UX 가 상당히 저하 된다.


해결 방안

의사결정 과정

Spring의 @Valid는 MVC 레벨에서 작동한다.
즉, 유효성 검사에 실패하면 컨트롤러 메서드가 호출되기 전에
Spring이 자동으로 MethodArgumentNotValidException을 발생시킨다.

이 예외는 우리가 정의한 전역 예외 처리기(@RestControllerAdvice)에서
가로채어 응답 형식을 커스터마이징할 수 있다.

결과적으로, 입력값 검증 실패에 대한 응답을 전역에서 통일감 있게 처리하는 것이
가장 효율적인 방식이라고 판단했다.

왜 전역 처리기를 사용하는가?

  • 이메일, 비밀번호 등 입력값 검증 항목은 대부분 컨트롤러 간에 동일하다
  • 이를 각 컨트롤러에서 매번 처리하면 중복 코드가 증가하고, 유지보수가 어려워진다
  • 전역 처리기를 사용하면
    공통 검증 로직을 한 곳에서 관리할 수 있어
    재사용성유지보수성이 향상된다

해결 과정

시도

처음에는 유효성 검사 실패 시, Spring이 자동으로 400 Bad Request를 응답해주긴 했지만,
응답 메시지는 다음과 같이 내부 구현 정보와 긴 에러 문자열만 포함하고 있었다.

이렇게 된다면, 어떤 필드가 잘못됐는지 구분이 불가능하다
예외 메시지에 내부 클래스 경로까지 포함되어 가독성이 매우 떨어진다
사용자에게 전혀 도움이 되지 않는 에러 포맷이다

해결

이제 사용자는 어떤 필드에서 어떤 문제가 발생했는지 명확하게 알 수 있고,
개발자도 예외 메시지를 구조적으로 관리할 수 있게 되었다.


해결 완료

회고

처음에는 Spring이 기본 제공하는 예외 메시지에 의존했기 때문에,
유효성 검증 실패 시 사용자에게 전달되는 정보가 거의 없었다.
단순히 "400 Bad Request"만 반환되고 어떤 필드가 잘못되었는지 알 수 없었기 때문에,
사용자 입장에서 매우 불친절한 UX였다.

이를 개선하기 위해 @RestControllerAdvice를 활용한 전역 예외 처리기를 직접 구현했고,
MethodArgumentNotValidException에서 각 필드별 오류 메시지를 추출하여
구조화된 JSON 형태로 응답하도록 변경했다.

그 결과, 사용자에게 의미 있는 피드백을 제공할 수 있게 되었고,
개발자 입장에서도 유지보수성과 확장성이 높아졌다.

전후 데이터 비교

이전 응답


- 너무 길고, 어디서 잘못됐는지 알 수 없다.
- 내부 코드 정보까지 보여서 보기 불편하다.


이후 응답

- 어떤 필드에 어떤 문제가 있는지 명확하게 보여준다.
- 사용자도, 프론트엔드도 쉽게 이해 가능하다.

profile
배우노라, 실험하노라, 기록하노라

0개의 댓글