package roomescape.common.exception import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KotlinLogging import org.springframework.http.ResponseEntity import org.springframework.http.converter.HttpMessageNotReadableException import org.springframework.web.bind.MethodArgumentNotValidException import org.springframework.web.bind.annotation.ExceptionHandler import org.springframework.web.bind.annotation.RestControllerAdvice import roomescape.common.dto.response.CommonErrorResponse import roomescape.common.dto.response.CommonErrorResponseV2 @RestControllerAdvice class ExceptionControllerAdvice( private val logger: KLogger = KotlinLogging.logger {} ) { @ExceptionHandler(value = [RoomescapeExceptionV2::class]) fun handleRoomException(e: RoomescapeExceptionV2): ResponseEntity { logger.error(e) { "message: ${e.message}" } val errorCode: ErrorCode = e.errorCode return ResponseEntity .status(errorCode.httpStatus) .body(CommonErrorResponseV2(errorCode, e.message)) } @ExceptionHandler(value = [RoomescapeException::class]) fun handleRoomEscapeException(e: RoomescapeException): ResponseEntity { logger.error(e) { "message: ${e.message}, invalidValue: ${e.invalidValue}" } return ResponseEntity .status(e.httpStatus) .body(CommonErrorResponse(e.errorType)) } @ExceptionHandler(value = [HttpMessageNotReadableException::class]) fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException): ResponseEntity { logger.error(e) { "message: ${e.message}" } val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE return ResponseEntity .status(errorCode.httpStatus) .body(CommonErrorResponseV2(errorCode, e.message ?: errorCode.message)) } @ExceptionHandler(value = [MethodArgumentNotValidException::class]) fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ResponseEntity { val message: String = e.bindingResult.allErrors .mapNotNull { it.defaultMessage } .joinToString(", ") logger.error(e) { "message: $message" } val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE return ResponseEntity .status(errorCode.httpStatus) .body(CommonErrorResponseV2(errorCode, message)) } @ExceptionHandler(value = [Exception::class]) fun handleException(e: Exception): ResponseEntity { logger.error(e) { "message: ${e.message}" } val errorCode: ErrorCode = CommonErrorCode.UNEXPECTED_SERVER_ERROR return ResponseEntity .status(errorCode.httpStatus) .body(CommonErrorResponseV2(errorCode)) } }