[Spring Boot]Exeption Handler 적용 에러 해결

한상욱·2024년 7월 8일
0

에러해결모음

목록 보기
4/10
post-thumbnail

사건의 발단

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은 우선순위가 후순위일지도 모르니 각 예외처리 핸들러는 우선순위를 지정해주자!

profile
자기주도적, 지속 성장하는 모바일앱 개발자의 기록

0개의 댓글