[#5]: 공통 기능 코틀린 마이그레이션 및 패키지 분리 #6

Merged
pricelees merged 20 commits from refactor/#5 into main 2025-07-14 05:05:48 +00:00
Showing only changes of commit 5b6c57ee2e - Show all commits

View File

@ -1,71 +1,75 @@
package roomescape.common.exception; package roomescape.common.exception
import java.util.stream.Collectors; import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import org.slf4j.Logger; import jakarta.servlet.http.HttpServletResponse
import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus
import org.springframework.context.support.DefaultMessageSourceResolvable; import org.springframework.http.converter.HttpMessageNotReadableException
import org.springframework.http.HttpStatus; import org.springframework.web.HttpRequestMethodNotSupportedException
import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.client.ResourceAccessException
import org.springframework.web.bind.annotation.RestControllerAdvice; import roomescape.common.dto.response.ErrorResponse
import org.springframework.web.client.ResourceAccessException;
import jakarta.servlet.http.HttpServletResponse;
import roomescape.common.dto.response.ErrorResponse;
@RestControllerAdvice @RestControllerAdvice
public class ExceptionControllerAdvice { class ExceptionControllerAdvice(
private val logger: KLogger = KotlinLogging.logger {}
) {
private final Logger logger = LoggerFactory.getLogger(getClass()); @ExceptionHandler(value = [RoomescapeException::class])
fun handleRoomEscapeException(
e: RoomescapeException,
response: HttpServletResponse
): ErrorResponse {
logger.error(e) { "message: ${e.message}, invalidValue: ${e.invalidValue}" }
response.status = e.httpStatus.value()
@ExceptionHandler(value = {RoomescapeException.class}) return ErrorResponse.of(e.errorType, e.message!!)
public ErrorResponse handleRoomEscapeException(RoomescapeException e, HttpServletResponse response) { }
logger.error("{}{}", e.getMessage(), e.getInvalidValue(), e);
response.setStatus(e.getHttpStatus().value());
return ErrorResponse.of(e.getErrorType(), e.getMessage());
}
@ExceptionHandler(ResourceAccessException.class) @ExceptionHandler(ResourceAccessException::class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponse handleResourceAccessException(ResourceAccessException e) { fun handleResourceAccessException(e: ResourceAccessException): ErrorResponse {
logger.error(e.getMessage(), e); logger.error(e) { "message: ${e.message}" }
return ErrorResponse.of(ErrorType.PAYMENT_SERVER_ERROR, ErrorType.PAYMENT_SERVER_ERROR.description);
}
@ExceptionHandler(value = HttpMessageNotReadableException.class) return ErrorResponse.of(ErrorType.PAYMENT_SERVER_ERROR, ErrorType.PAYMENT_SERVER_ERROR.description)
@ResponseStatus(HttpStatus.BAD_REQUEST) }
public ErrorResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
logger.error(e.getMessage(), e);
return ErrorResponse.of(ErrorType.INVALID_REQUEST_DATA_TYPE,
ErrorType.INVALID_REQUEST_DATA_TYPE.description);
}
@ExceptionHandler(value = MethodArgumentNotValidException.class) @ExceptionHandler(value = [HttpMessageNotReadableException::class])
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException): ErrorResponse {
String messages = e.getBindingResult().getAllErrors().stream() logger.error(e) { "message: ${e.message}" }
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining(", "));
logger.error(messages, e); return ErrorResponse.of(ErrorType.INVALID_REQUEST_DATA_TYPE,
return ErrorResponse.of(ErrorType.INVALID_REQUEST_DATA, messages); ErrorType.INVALID_REQUEST_DATA_TYPE.description)
} }
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class) @ExceptionHandler(value = [MethodArgumentNotValidException::class])
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) @ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ErrorResponse {
logger.error(e.getMessage(), e); val messages: String = e.bindingResult.allErrors
return ErrorResponse.of(ErrorType.METHOD_NOT_ALLOWED, ErrorType.METHOD_NOT_ALLOWED.description); .mapNotNull { it.defaultMessage }
} .joinToString(", ")
logger.error(e) { "message: $messages" }
@ExceptionHandler(value = Exception.class) return ErrorResponse.of(ErrorType.INVALID_REQUEST_DATA, messages)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) }
public ErrorResponse handleException(Exception e) {
logger.error(e.getMessage(), e); @ExceptionHandler(value = [HttpRequestMethodNotSupportedException::class])
return ErrorResponse.of(ErrorType.INTERNAL_SERVER_ERROR, ErrorType.INTERNAL_SERVER_ERROR.description); @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
} fun handleHttpRequestMethodNotSupportedException(e: HttpRequestMethodNotSupportedException): ErrorResponse {
logger.error(e) { "message: ${e.message}" }
return ErrorResponse.of(ErrorType.METHOD_NOT_ALLOWED, ErrorType.METHOD_NOT_ALLOWED.description)
}
@ExceptionHandler(value = [Exception::class])
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
fun handleException(e: Exception): ErrorResponse {
logger.error(e) { "message: ${e.message}" }
return ErrorResponse.of(ErrorType.UNEXPECTED_ERROR, ErrorType.UNEXPECTED_ERROR.description)
}
} }