Language & Framework/WebFlux

[WebFlux] WebFlux Custom Exception 생성하기

수미수 2023. 9. 26. 19:48
반응형

들어가기 전

 지난 글에서는 Spring WebFlux 에서 여러 오류 및 예외 처리 시 전역 오류 및 예외 처리에 관해서 샘플 코드와 함께 설명 하였다. 기본적인 오류 및 예외 처리가 아닌 실제 운영을 하면서 비지니스 로직을 처리하면서 커스텀 예외를 만들어서 사용하는게 대부분일 것이다. 예를 들면, 고객 정보를 조회 하는데 고객 정보가 없는 경우 비지니스 예외 처리를 발생 하여 그 이후의 코드 실행이 되지 않도록 구성 할 수 있다. 이번 글에서는 이러한 도메인 영역 즉, 특정 비지니스를 수행 하면서 예외를 발생 시키기 위한 Custom Exception 클래스 생성과 이를 발생 시켜 이전 글에서 설명한 전역에서 이를 핸들링 하는 방법에 대해서 설명 하고자 한다.

CustomException 정의 하기

  Spring WebFlux 에서 Custom Exception 을 생성하는 방법은 기존 MVC 방법과 동일하다. 일반적으로 Custom Exception 은 Runtime Exception 을 상속 받아서 정의 한다. 해당 글에서는 "인증 실패라는 비지니스 예외"를 발생 시킬 때 사용하는 Custom Exception 을 생성하여 샘플 코드와 같이 설명 한다. Custom Exception 을 사용하기 위해, 예외처리 구분을 위한 ResponseCode, 예외 메시지 출력을 위한 Exception Message 관리 클래스를 생성 할 것이다. 보다 자세한 예외 표준은 별도의 글은 추가로 작성 예정이다.

ApiResponseCode 클래스 생성

  아래 소스는 업무 별 예외 카테고리 코드를 정의 하였다. 즉 기본적인 Http Status 코드 외 정상적인 응답인지 비지니스 또는 서버 상의 오류인지 응답으로 사용하기 위한 코드를 분류 하여 사용 하였다.

enum class ApiResponseCode(
    val code: String,
    val message: String
){
    OK("0000","정상"),
    VALID_FAIL("0030", "유효성검사 실패하였습니다."),
    NO_DATA("0040", "결과값이 존재하지 않습니다."),
    ERROR("0099", "오류"),
}

CustomExceptionMessage 클래스 생성

  아래 소스는 업무 별 예외에 대한 실제 업무 세부 코드와 메시지 정보를 관리 하는 클래스이다. 실제 Custom Exception 이 발생 되고 응답이 되면, 에러 코드와 에러 메시지에 맵핑 되는 정보이다.

class CustomExceptionMessage (
    val code: String,
    val message: String
) {
    companion object {
      
	val AUTHENTICATION_FAILED = CustomExceptionMessage("000902", "인증 정보가 없습니다.")
    
    }
}

AuthenticationFailedException 클래스 생성

  아래 코드는 위 두 클래스를 활용하여, 실제 인증 실패 시 예외 처리를 위한 Custom Exception 샘플 소스이다. 

class AuthenticationFailedException(apiResponse: ApiResponseCode, customException: CustomExceptionMessage): RuntimeException() {
    val status: ApiResponseCode = apiResponse
    val customException: CustomExceptionMessage = customException
}

Custom Exception 발생 시키기

  해당 절에서는 실제 업무상에서 위에서 생성한 업무 Custom Exception 을 발생 시켰는지 설명 한다. 아래 소스는 인증 체크 후 인증 정보가 존재 하지 않는 경우 AuthenticationFailedException 을 발생 시키는 예제 이다. 

  해당 메서드는 인증 토큰으로 부터 정보를 불러와서 정보가 없는 경우 위에서 정의 했던 Response Code 와 예외에 대한 메시지 코드 및 메시지 정보를 바탕으로 비지니스 예외를 발생 시킨다.

.................

	fun postMarketingDisAgreement(): Mono<ResponseEntity<MarketingAgreementInfoDto>> {
        return ReactiveSecurityContextHolder.getContext()
            .map {
                ClientUtil.getCustomerIdFromToken(it)
            }
            .switchIfEmpty(Mono.defer { throw AuthenticationFailedException(
                ApiResponseCode.NO_DATA,
                CustomExceptionMessage.AUTHENTICATION_FAILED) })
            .flatMap { marketingDisAgreementPostService.postCustomerMarketingDisAgreement(it) }
            .map { s -> ResponseEntity(s, HttpStatus.OK) }

    }
    
.................

결론

  해당 글에서는 Custom Exception 을 생성하고, 이를 발생 시키는 방법에 대해서 설명 하였다. 보다 세부적으로 Custom Exception 을 핸들링 하고자 한다면, 이전 글에서 GloabalErrorExceptionHandler 클래스의 renderErrorResponse 메서드에서 해당 Exception 발생 된 클래스를 체크 하여 보다 세밀하게 Exception 을 핸들링 할 수 있다.

반응형