refactor: 새로운 커스텀 예외 전환으로 기존 커스텀 예외 제거

This commit is contained in:
이상진 2025-07-24 10:02:18 +09:00
parent 31538c2632
commit 74f87e4a2a
10 changed files with 22 additions and 101 deletions

View File

@ -1,8 +1,8 @@
package roomescape.auth.exception
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class AuthException(
override val errorCode: AuthErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)

View File

@ -2,7 +2,6 @@ package roomescape.common.dto.response
import com.fasterxml.jackson.annotation.JsonInclude
import roomescape.common.exception.ErrorCode
import roomescape.common.exception.ErrorType
@JsonInclude(JsonInclude.Include.NON_NULL)
data class CommonApiResponse<T>(
@ -10,11 +9,6 @@ data class CommonApiResponse<T>(
)
data class CommonErrorResponse(
val errorType: ErrorType,
val message: String? = errorType.description
)
data class CommonErrorResponseV2(
val code: String,
val message: String
) {

View File

@ -1,53 +0,0 @@
package roomescape.common.exception
enum class ErrorType(
val description: String
) {
// 400 Bad Request
REQUEST_DATA_BLANK("요청 데이터에 유효하지 않은 값(null OR 공백)이 포함되어있습니다."),
INVALID_REQUEST_DATA_TYPE("요청 데이터 형식이 올바르지 않습니다."),
INVALID_REQUEST_DATA("요청 데이터 값이 올바르지 않습니다."),
INVALID_DATE_RANGE("종료 날짜는 시작 날짜 이전일 수 없습니다."),
HAS_RESERVATION_OR_WAITING("같은 테마에 대한 예약(대기)는 한 번만 가능합니다."),
// 401 Unauthorized
EXPIRED_TOKEN("토큰이 만료되었습니다. 다시 로그인 해주세요."),
UNSUPPORTED_TOKEN("지원하지 않는 JWT 토큰입니다."),
MALFORMED_TOKEN("형식이 맞지 않는 JWT 토큰입니다."),
INVALID_SIGNATURE_TOKEN("잘못된 JWT 토큰 Signature 입니다."),
ILLEGAL_TOKEN("JWT 토큰의 Claim 이 비어있습니다."),
INVALID_TOKEN("JWT 토큰이 존재하지 않거나 유효하지 않습니다."),
NOT_EXIST_COOKIE("쿠키가 존재하지 않습니다. 로그인이 필요한 서비스입니다."),
// 403 Forbidden
LOGIN_REQUIRED("로그인이 필요한 서비스입니다."),
PERMISSION_DOES_NOT_EXIST("접근 권한이 존재하지 않습니다."),
// 404 Not Found
MEMBER_NOT_FOUND("회원(Member) 정보가 존재하지 않습니다."),
RESERVATION_NOT_FOUND("예약(Reservation) 정보가 존재하지 않습니다."),
TIME_NOT_FOUND("예약 시간(Time) 정보가 존재하지 않습니다."),
THEME_NOT_FOUND("테마(Theme) 정보가 존재하지 않습니다."),
PAYMENT_NOT_FOUND("결제(Payment) 정보가 존재하지 않습니다."),
// 405 Method Not Allowed
METHOD_NOT_ALLOWED("지원하지 않는 HTTP Method 입니다."),
// 409 Conflict
TIME_IS_USED_CONFLICT("삭제할 수 없는 시간대입니다. 예약이 존재하는지 확인해주세요."),
THEME_IS_USED_CONFLICT("삭제할 수 없는 테마입니다. 예약이 존재하는지 확인해주세요."),
TIME_DUPLICATED("이미 해당 시간이 존재합니다."),
THEME_DUPLICATED("같은 이름의 테마가 존재합니다."),
RESERVATION_DUPLICATED("해당 시간에 이미 예약이 존재합니다."),
RESERVATION_PERIOD_IN_PAST("이미 지난 시간대는 예약할 수 없습니다."),
CANCELED_BEFORE_PAYMENT("취소 시간이 결제 시간 이전일 수 없습니다."),
// 500 Internal Server Error,
INTERNAL_SERVER_ERROR("서버 내부에서 에러가 발생하였습니다."),
UNEXPECTED_ERROR("예상치 못한 에러가 발생하였습니다. 잠시 후 다시 시도해주세요."),
// Payment Error
PAYMENT_ERROR("결제(취소)에 실패했습니다. 결제(취소) 정보를 확인해주세요."),
PAYMENT_SERVER_ERROR("결제 서버에서 에러가 발생하였습니다. 잠시 후 다시 시도해주세요.")
;
}

View File

@ -8,43 +8,33 @@ 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<CommonErrorResponseV2> {
@ExceptionHandler(value = [RoomescapeException::class])
fun handleRoomException(e: RoomescapeException): ResponseEntity<CommonErrorResponse> {
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<CommonErrorResponse> {
logger.error(e) { "message: ${e.message}, invalidValue: ${e.invalidValue}" }
return ResponseEntity
.status(e.httpStatus)
.body(CommonErrorResponse(e.errorType))
.body(CommonErrorResponse(errorCode, e.message))
}
@ExceptionHandler(value = [HttpMessageNotReadableException::class])
fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException): ResponseEntity<CommonErrorResponseV2> {
fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException): ResponseEntity<CommonErrorResponse> {
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))
.body(CommonErrorResponse(errorCode))
}
@ExceptionHandler(value = [MethodArgumentNotValidException::class])
fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ResponseEntity<CommonErrorResponseV2> {
fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ResponseEntity<CommonErrorResponse> {
val message: String = e.bindingResult.allErrors
.mapNotNull { it.defaultMessage }
.joinToString(", ")
@ -53,16 +43,16 @@ class ExceptionControllerAdvice(
val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE
return ResponseEntity
.status(errorCode.httpStatus)
.body(CommonErrorResponseV2(errorCode, message))
.body(CommonErrorResponse(errorCode))
}
@ExceptionHandler(value = [Exception::class])
fun handleException(e: Exception): ResponseEntity<CommonErrorResponseV2> {
fun handleException(e: Exception): ResponseEntity<CommonErrorResponse> {
logger.error(e) { "message: ${e.message}" }
val errorCode: ErrorCode = CommonErrorCode.UNEXPECTED_SERVER_ERROR
return ResponseEntity
.status(errorCode.httpStatus)
.body(CommonErrorResponseV2(errorCode))
.body(CommonErrorResponse(errorCode))
}
}

View File

@ -1,16 +1,6 @@
package roomescape.common.exception
import org.springframework.http.HttpStatusCode
class RoomescapeException(
val errorType: ErrorType,
val invalidValue: String? = "",
val httpStatus: HttpStatusCode,
) : RuntimeException(errorType.description) {
constructor(errorType: ErrorType, httpStatus: HttpStatusCode) : this(errorType, null, httpStatus)
}
open class RoomescapeExceptionV2(
open class RoomescapeException(
open val errorCode: ErrorCode,
override val message: String = errorCode.message
) : RuntimeException(message)

View File

@ -1,8 +1,8 @@
package roomescape.member.exception
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class MemberException(
override val errorCode: MemberErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)

View File

@ -1,8 +1,8 @@
package roomescape.payment.exception
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class PaymentException(
override val errorCode: PaymentErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)

View File

@ -1,9 +1,9 @@
package roomescape.reservation.exception
import roomescape.common.exception.ErrorCode
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class ReservationException(
override val errorCode: ErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)

View File

@ -1,8 +1,8 @@
package roomescape.theme.exception
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class ThemeException(
override val errorCode: ThemeErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)

View File

@ -1,9 +1,9 @@
package roomescape.time.exception
import roomescape.common.exception.ErrorCode
import roomescape.common.exception.RoomescapeExceptionV2
import roomescape.common.exception.RoomescapeException
class TimeException(
override val errorCode: ErrorCode,
override val message: String = errorCode.message
) : RoomescapeExceptionV2(errorCode, message)
) : RoomescapeException(errorCode, message)