[Spring] Exception 중복 정의 문제

White 와잇·2024년 6월 20일

Spring

목록 보기
6/9
post-thumbnail

개요

@ExceptionHandler를 사용한 Exception 처리 코드를 작성 중에
BindExceptionMethodArgumentNotValidException 이 두 가지 예외처리는 핸들러를 정의하면 스프링 서버가 뜰 때 오류가 난다.

BindException 핸들러를 다음과 같이 정의하였다.

트러블슈팅

에러 로그

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'handlerExceptionResolver' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Failed to instantiate [org.springframework.web.servlet.HandlerExceptionResolver]: Factory method 'handlerExceptionResolver' threw exception with message: Ambiguous @ExceptionHandler method mapped for [class org.springframework.validation.BindException]: {public org.springframework.http.ResponseEntity [내가 정의한 Exception 클래스 경로].handleCustomException(org.springframework.validation.BindException), public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception}

심경이 복잡해진다
끊어서 조금 살펴보면,

Ambiguous @ExceptionHandler method mapped for [class org.springframework.validation.BindException] :
예외처리를 잡아줄 핸들러를 정의했는데 이미 어딘가에 정의된 코드가 있어서 어느 핸들러로 보내줘야 하는지 handlerExceptionResolver가 모른다는 에러인 것 같다.

{public org.springframework.http.ResponseEntity [내가 정의한 ExceptionHandler 클래스 경로].handleCustomException(org.springframework.validation.BindException),
내가 정의한 핸들러 메서드와

public final org.springframework.http.ResponseEntity org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception}
프레임워크에 의해 이미 존재하는 핸들러 메서드를 알려준다.

해결법

org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException 파일을 확인해보았다.

handleException()이라는 핸들러가 이미 정의되어 있었고, BindException도 포함되어있다.

handleBindException() 메서드가 실질적으로 BindException 핸들러이므로 이것을 오버라이딩하면 커스터마이즈 할 수 있다.

코드를 보니 handleBindException()은 스프링 6.0버전부터 더는 지원하지 않는 메서드라서 설명처럼 MethodArgumentNotValidException으로 대체하기로 하였다.

MethodArgumentNotValidException의 핸들러는 handleMethodArgumentNotValid() 라서 다음 메서드를 오버라이딩 하면 된다.

결과

handleMethodArgumentNotValid()@Override 한 코드

실행하면 스프링 서버가 잘 돌아감.

profile
웹개발 도전! 데브옵스 도전!

0개의 댓글