📒 상황
data class FacilityReq(
@NotNull
val category: Category,
@NotBlank
val name: String
)
◼ 시설 등록 요청 DTO를 위와 같이 작성하고 name 값을 넣지 않고 요청을 보내면 에러가 발생한다.
💥 기대했던 에러는 name은 null이 될 수 없다는 에러였는데, 에러 API 응답으로 설정한 값과 다른 값이 응답으로 왔다.
📒 원인
name을 NotNull 타입인 String으로 설정해서 null을 허용하지 않는 타입으로 정의했다.
이로 인해, name이 null로 채워지게 된다면 @field:NotBlank validation 로직을 타기 전에 변수에 값을 할당하는 과정에서 예외가 발생하게 되어 다음과 같은 에러가 발생한다.
💥 HttpMessageNotReadableException
📒 해결 방법
◼ Dto에서 NotNull 타입으로 Validation을 진행하고자 하면 다음과 같이 MethodArgumentNotValid 예외를 처리하는 것이 아닌 HttpMessageNotReadableException로 예외를 처리해야 한다.
🤦♂️ MissingKotlinParameterException -> Deprecated
@RestControllerAdvice
class ExceptionHandler : ResponseEntityExceptionHandler() {
override fun handleHttpMessageNotReadable(
ex: HttpMessageNotReadableException,
headers: HttpHeaders,
status: HttpStatusCode,
request: WebRequest
): ResponseEntity<Any>? {
logger.error("[HttpMessageNotReadableException] ${ex.message}")
val errorMessage = when (val cause = ex.cause) {
is MissingKotlinParameterException -> "${cause.parameter.name} is null"
else -> "유효하지 않은 요청입니다"
}
return ResponseEntity.status(ErrorCode.REQUEST_RESOURCE_NOT_VALID.httpStatus)
.body(ApiResponse.error(ErrorCode.REQUEST_RESOURCE_NOT_VALID.code, errorMessage))
}
}
◼ jackson-module-kotlion 2.16 부터 Deprecated 되었다.
✔ MismatchedInputException
override fun handleHttpMessageNotReadable(
ex: HttpMessageNotReadableException,
headers: HttpHeaders,
status: HttpStatusCode,
request: WebRequest
): ResponseEntity<Any>? {
logger.error("[HttpMessageNotReadableException] ${ex.message}")
val listOf = listOf("a", "b", "c")
println(listOf.joinToString() { it.toString() })
val errorMessage = when (val cause = ex.cause) {
is MismatchedInputException -> "${cause.path.joinToString() { it.fieldName }} is null"
else -> "유효하지 않은 요청입니다"
}
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiErrorResponse(errorMessage))
}
◼ 위 코드를 작성하고 다시 요청을 보내면 다음과 같이 응답 값이 처리된다.
📒 결론
◼ Kotlin에서 NotNull 타입을 사용하면서, Null에 대한 Validation을 체크하려면 Java와 같이 Validation 어노테이션을 통해서 처리하는 것이 아닌 HttpMessageNotReadableException 예외를 잡아서 처리해야 한다.
'트러블 슈팅' 카테고리의 다른 글
Jpa Validate 에러 (with. Oracle DB, h2) (0) | 2023.05.30 |
---|---|
Kotest + 생성자 Bean 주입 (0) | 2023.05.27 |
[Junit5] JPA metamodel must not be empty! (0) | 2022.11.22 |
[Junit5] org.mockito.exceptions.misusing.MissingMethodInvocationException (0) | 2022.11.21 |
[Spring] Spring Security + Junit5 (0) | 2022.11.15 |