Spring Boot에서 특정 Controller는 CustomException을 제작하여 해당 예외를 처리하는 Exception Handler를 만들었는데요. 의도하지 않은 Exception Handler가 작동되었습니다.
Exception Handler는 여러개를 만들어서 각각 상황에 맞는 예외상황을 처리하고 있었는데, 아무래도 우선순위가 기본 예외처리에 걸리는 것 같았습니다. 구글링을 해보니 @Order 를 통해서 우선순위를 결정할 수 있다고 하네요!
@Order(value = 1)
@RestControllerAdvice
class MemberExceptionHandler {
@ExceptionHandler(InvalidEmailException::class)
protected fun invalidEmailExceptionHandler(exception: InvalidEmailException)
: ResponseEntity<BaseResponse<Map<String, String>>> {
val error = mapOf(exception.fieldName to (exception.message ?: "Not Exception Message"))
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.body(BaseResponse(
status = ResultStatus.ERROR.name,
data = error,
resultMsg = ResultStatus.ERROR.msg,
))
}
@ExceptionHandler(BadCredentialsException::class)
protected fun badCredentialExceptionHandler(exception : BadCredentialsException)
: ResponseEntity<BaseResponse<Map<String, String>>> {
val errors = mapOf("로그인 실패" to "이메일 혹은 비밀번호를 확인하세요!")
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
BaseResponse(
status = ResultStatus.ERROR.name,
data = errors,
resultMsg = ResultStatus.ERROR.msg
)
)
}
}
@Order(value = 2)
@RestControllerAdvice
class CommonExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException::class)
protected fun methodArgumentNotValidExceptionHandler(
exception: MethodArgumentNotValidException
) : ResponseEntity<BaseResponse<Map<String, String>>> {
var errors = mutableMapOf<String, String>()
exception.bindingResult.allErrors.forEach { error ->
val fieldName = (error as FieldError).field
val errorMsg = error.defaultMessage
errors[fieldName] = errorMsg ?: "에러 메시지가 존재하지 않습니다!"
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
BaseResponse(
status = ResultStatus.ERROR.name,
data = errors,
resultMsg = ResultStatus.ERROR.msg,
)
)
}
@ExceptionHandler(NoHandlerFoundException::class)
protected fun notFoundApiUrlExceptionHandler(exception: NoHandlerFoundException) :
ResponseEntity<BaseResponse<Any>> {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(
BaseResponse(status = ResultStatus.ERROR.name, resultMsg = "존재하지 않는 Api Url 입니다.")
)
}
@ExceptionHandler(Exception::class)
protected fun defaultExceptionHandler(exception: Exception) :
ResponseEntity<BaseResponse<Any>> {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(
BaseResponse(status = ResultStatus.ERROR.name, resultMsg = ResultStatus.ERROR.msg)
)
}
}
개발자가 커스텀 제작한 Exception은 우선순위가 후순위일지도 모르니 각 예외처리 핸들러는 우선순위를 지정해주자!