generated from pricelees/issue-pr-template
refactor: ExceptionHandler에서 API 에러 응답을 로깅하도록 수정
This commit is contained in:
parent
7e0bfd9f92
commit
5e0a52cb47
@ -2,55 +2,110 @@ package roomescape.common.exception
|
|||||||
|
|
||||||
import io.github.oshai.kotlinlogging.KLogger
|
import io.github.oshai.kotlinlogging.KLogger
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import org.slf4j.MDC
|
||||||
|
import org.springframework.http.HttpStatus
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
import org.springframework.http.converter.HttpMessageNotReadableException
|
import org.springframework.http.converter.HttpMessageNotReadableException
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException
|
import org.springframework.web.bind.MethodArgumentNotValidException
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice
|
import org.springframework.web.bind.annotation.RestControllerAdvice
|
||||||
|
import roomescape.auth.exception.AuthException
|
||||||
import roomescape.common.dto.response.CommonErrorResponse
|
import roomescape.common.dto.response.CommonErrorResponse
|
||||||
|
import roomescape.common.log.ApiLogMessageConverter
|
||||||
|
import roomescape.common.log.ConvertResponseMessageRequest
|
||||||
|
import roomescape.common.log.LogType
|
||||||
|
|
||||||
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
class ExceptionControllerAdvice(
|
class ExceptionControllerAdvice(
|
||||||
private val log: KLogger = KotlinLogging.logger {}
|
private val messageConverter: ApiLogMessageConverter
|
||||||
) {
|
) {
|
||||||
@ExceptionHandler(value = [RoomescapeException::class])
|
@ExceptionHandler(value = [RoomescapeException::class])
|
||||||
fun handleRoomException(e: RoomescapeException): ResponseEntity<CommonErrorResponse> {
|
fun handleRoomException(e: RoomescapeException): ResponseEntity<CommonErrorResponse> {
|
||||||
val errorCode: ErrorCode = e.errorCode
|
val errorCode: ErrorCode = e.errorCode
|
||||||
|
val httpStatus: HttpStatus = errorCode.httpStatus
|
||||||
|
val errorResponse = CommonErrorResponse(errorCode)
|
||||||
|
|
||||||
|
val type = if (e is AuthException) LogType.AUTHENTICATION_FAILURE else LogType.APPLICATION_FAILURE
|
||||||
|
logException(
|
||||||
|
type = type,
|
||||||
|
httpStatus = httpStatus.value(),
|
||||||
|
errorResponse = errorResponse,
|
||||||
|
exception = e
|
||||||
|
)
|
||||||
|
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.status(errorCode.httpStatus)
|
.status(httpStatus)
|
||||||
.body(CommonErrorResponse(errorCode, e.message))
|
.body(errorResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [HttpMessageNotReadableException::class])
|
@ExceptionHandler(value = [MethodArgumentNotValidException::class, HttpMessageNotReadableException::class])
|
||||||
fun handleHttpMessageNotReadableException(e: HttpMessageNotReadableException): ResponseEntity<CommonErrorResponse> {
|
fun handleInvalidRequestValueException(e: Exception): ResponseEntity<CommonErrorResponse> {
|
||||||
log.debug { "message: ${e.message}" }
|
val message: String = if (e is MethodArgumentNotValidException) {
|
||||||
|
e.bindingResult.allErrors
|
||||||
|
.mapNotNull { it.defaultMessage }
|
||||||
|
.joinToString(", ")
|
||||||
|
} else {
|
||||||
|
e.message!!
|
||||||
|
}
|
||||||
|
log.debug { "[ExceptionControllerAdvice] Invalid Request Value Exception occurred: $message" }
|
||||||
|
|
||||||
val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE
|
val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE
|
||||||
return ResponseEntity
|
val httpStatus: HttpStatus = errorCode.httpStatus
|
||||||
.status(errorCode.httpStatus)
|
val errorResponse = CommonErrorResponse(errorCode)
|
||||||
.body(CommonErrorResponse(errorCode))
|
|
||||||
}
|
|
||||||
|
|
||||||
@ExceptionHandler(value = [MethodArgumentNotValidException::class])
|
logException(
|
||||||
fun handleMethodArgumentNotValidException(e: MethodArgumentNotValidException): ResponseEntity<CommonErrorResponse> {
|
type = LogType.APPLICATION_FAILURE,
|
||||||
val message: String = e.bindingResult.allErrors
|
httpStatus = httpStatus.value(),
|
||||||
.mapNotNull { it.defaultMessage }
|
errorResponse = errorResponse,
|
||||||
.joinToString(", ")
|
exception = e
|
||||||
log.debug { "message: $message" }
|
)
|
||||||
|
|
||||||
val errorCode: ErrorCode = CommonErrorCode.INVALID_INPUT_VALUE
|
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.status(errorCode.httpStatus)
|
.status(httpStatus)
|
||||||
.body(CommonErrorResponse(errorCode))
|
.body(errorResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [Exception::class])
|
@ExceptionHandler(value = [Exception::class])
|
||||||
fun handleException(e: Exception): ResponseEntity<CommonErrorResponse> {
|
fun handleException(e: Exception): ResponseEntity<CommonErrorResponse> {
|
||||||
log.error(e) { "message: ${e.message}" }
|
log.error(e) { "[ExceptionControllerAdvice] Unexpected exception occurred: ${e.message}" }
|
||||||
|
|
||||||
val errorCode: ErrorCode = CommonErrorCode.UNEXPECTED_SERVER_ERROR
|
val errorCode: ErrorCode = CommonErrorCode.UNEXPECTED_SERVER_ERROR
|
||||||
|
val httpStatus: HttpStatus = errorCode.httpStatus
|
||||||
|
val errorResponse = CommonErrorResponse(errorCode)
|
||||||
|
|
||||||
|
logException(
|
||||||
|
type = LogType.UNHANDLED_EXCEPTION,
|
||||||
|
httpStatus = httpStatus.value(),
|
||||||
|
errorResponse = errorResponse,
|
||||||
|
exception = e
|
||||||
|
)
|
||||||
|
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
.status(errorCode.httpStatus)
|
.status(httpStatus)
|
||||||
.body(CommonErrorResponse(errorCode))
|
.body(errorResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logException(
|
||||||
|
type: LogType,
|
||||||
|
httpStatus: Int,
|
||||||
|
errorResponse: CommonErrorResponse,
|
||||||
|
exception: Exception
|
||||||
|
) {
|
||||||
|
val commonRequest = ConvertResponseMessageRequest(
|
||||||
|
type = type,
|
||||||
|
httpStatus = httpStatus,
|
||||||
|
startTime = MDC.get("startTime")?.toLongOrNull(),
|
||||||
|
body = errorResponse,
|
||||||
|
)
|
||||||
|
|
||||||
|
val logMessage = if (errorResponse.message == exception.message) {
|
||||||
|
messageConverter.convertToResponseMessage(commonRequest)
|
||||||
|
} else {
|
||||||
|
messageConverter.convertToResponseMessage(commonRequest.copy(exception = exception))
|
||||||
|
}
|
||||||
|
|
||||||
|
log.warn { logMessage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user