본문 바로가기
Spring

[Spring] MissingKotlinParameterException을 ExceptionHandler로 처리 하는 방법

by 노력남자 2023. 1. 15.
반응형

MissingKotlinParameterException이 발생하는 이유를 알아보고 이를 ExceptionHandler로 처리하는 방법을 알아보자.

 

MissingKotlinParameterException 발생 원인 

 

api request를 @RequestBody로 받을 때 받는 객체의 not null인 필드에 null이 들어온 경우 발생한다.
 
아래 api를 예를 들어 설명하겠다.
 
@RestController
class CourseController {

    @PostMapping("/course")
    fun saveCourse(@RequestBody course: Course): String {
        return ""
    }
}

data class Course(
    val name: String
)

 

/course api에서 사용하는 Course 객체의 name 필드는 nullable이 아니다.

 
{
    "name": null
}

 

 

nullable이 아닌 name 필드에 null을 넣어서 보내면 아래와 같이 HttpMessageNotReadableException에러가 발생한다.
더보기
curl --location --request POST 'http://localhost:8080/course' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": null
}'
 
터미널에서 실행!

 

.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Instantiation of [simple type, class com.example.kotlintest.Course] value failed for JSON property name due to missing (therefore NULL) value for creator parameter name which is a non-nullable type; nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: Instantiation of [simple type, class com.example.kotlintest.Course] value failed for JSON property name due to missing (therefore NULL) value for creator parameter name which is a non-nullable type<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 5, column: 1] (through reference chain: com.example.kotlintest.Course["name"])]


MissingKotlinParameterException을 ExceptionHandler으로 잡는 방법


자세히 보면 MissingKotlinParameterException을 HttpMessageNotReadableException에서 발생키기고 있다.
(Spring mvc는 HttpMessageNotReadableException, webflux는 CodecException에서 발생시킨다.)

에러를 throw 하는 곳을 찾아가보자.

AbstractJackson2HttpMessageConverter.java 파일 390번째 라인에 있다.

 

 

그냥 HttpMessageNotReadableException만 잡으면 될 거 같다.....라고 생각했지만

 


HttpMessageNotReadableException이 발생하는 cause는 생각보다 많았다.

그래서 HttpMessageNotReadableException로 잡고 cause 가 MissingKotlinParameterException인 경우를 처리해야 한다.

 

@RestControllerAdvice
class ExceptionHandler {

    val log = KotlinLogging.logger {}

    @ExceptionHandler(HttpMessageNotReadableException::class)
    fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException) {

        when (val caused = e.cause) {
            is MissingKotlinParameterException -> {
                log.warn(e) { "${caused.parameter.name} 필드가 누락되었습니다." }
            }
            else -> throw e
        }
    }
}


위와 같이 정의한 후 아까 위처럼 다시 name에 null을 넣어서 호출하면

더보기
curl --location --request POST 'http://localhost:8080/course' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": null
}'
 
터미널에서 실행!

 


name 필드가 누락되었다고 나온다.

반응형

댓글