generated from pricelees/issue-pr-template
[#41] 예약 스키마 재정의 #42
@ -2,6 +2,7 @@ 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 jakarta.servlet.http.HttpServletRequest
|
||||||
import org.slf4j.MDC
|
import org.slf4j.MDC
|
||||||
import org.springframework.http.HttpStatus
|
import org.springframework.http.HttpStatus
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
@ -14,6 +15,7 @@ import roomescape.common.dto.response.CommonErrorResponse
|
|||||||
import roomescape.common.log.ApiLogMessageConverter
|
import roomescape.common.log.ApiLogMessageConverter
|
||||||
import roomescape.common.log.ConvertResponseMessageRequest
|
import roomescape.common.log.ConvertResponseMessageRequest
|
||||||
import roomescape.common.log.LogType
|
import roomescape.common.log.LogType
|
||||||
|
import roomescape.common.log.getEndpoint
|
||||||
|
|
||||||
private val log: KLogger = KotlinLogging.logger {}
|
private val log: KLogger = KotlinLogging.logger {}
|
||||||
|
|
||||||
@ -22,7 +24,10 @@ class ExceptionControllerAdvice(
|
|||||||
private val messageConverter: ApiLogMessageConverter
|
private val messageConverter: ApiLogMessageConverter
|
||||||
) {
|
) {
|
||||||
@ExceptionHandler(value = [RoomescapeException::class])
|
@ExceptionHandler(value = [RoomescapeException::class])
|
||||||
fun handleRoomException(e: RoomescapeException): ResponseEntity<CommonErrorResponse> {
|
fun handleRoomException(
|
||||||
|
servletRequest: HttpServletRequest,
|
||||||
|
e: RoomescapeException
|
||||||
|
): ResponseEntity<CommonErrorResponse> {
|
||||||
val errorCode: ErrorCode = e.errorCode
|
val errorCode: ErrorCode = e.errorCode
|
||||||
val httpStatus: HttpStatus = errorCode.httpStatus
|
val httpStatus: HttpStatus = errorCode.httpStatus
|
||||||
val errorResponse = CommonErrorResponse(errorCode)
|
val errorResponse = CommonErrorResponse(errorCode)
|
||||||
@ -30,6 +35,7 @@ class ExceptionControllerAdvice(
|
|||||||
val type = if (e is AuthException) LogType.AUTHENTICATION_FAILURE else LogType.APPLICATION_FAILURE
|
val type = if (e is AuthException) LogType.AUTHENTICATION_FAILURE else LogType.APPLICATION_FAILURE
|
||||||
logException(
|
logException(
|
||||||
type = type,
|
type = type,
|
||||||
|
servletRequest = servletRequest,
|
||||||
httpStatus = httpStatus.value(),
|
httpStatus = httpStatus.value(),
|
||||||
errorResponse = errorResponse,
|
errorResponse = errorResponse,
|
||||||
exception = e
|
exception = e
|
||||||
@ -41,7 +47,10 @@ class ExceptionControllerAdvice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [MethodArgumentNotValidException::class, HttpMessageNotReadableException::class])
|
@ExceptionHandler(value = [MethodArgumentNotValidException::class, HttpMessageNotReadableException::class])
|
||||||
fun handleInvalidRequestValueException(e: Exception): ResponseEntity<CommonErrorResponse> {
|
fun handleInvalidRequestValueException(
|
||||||
|
servletRequest: HttpServletRequest,
|
||||||
|
e: Exception
|
||||||
|
): ResponseEntity<CommonErrorResponse> {
|
||||||
val message: String = if (e is MethodArgumentNotValidException) {
|
val message: String = if (e is MethodArgumentNotValidException) {
|
||||||
e.bindingResult.allErrors
|
e.bindingResult.allErrors
|
||||||
.mapNotNull { it.defaultMessage }
|
.mapNotNull { it.defaultMessage }
|
||||||
@ -57,6 +66,7 @@ class ExceptionControllerAdvice(
|
|||||||
|
|
||||||
logException(
|
logException(
|
||||||
type = LogType.APPLICATION_FAILURE,
|
type = LogType.APPLICATION_FAILURE,
|
||||||
|
servletRequest = servletRequest,
|
||||||
httpStatus = httpStatus.value(),
|
httpStatus = httpStatus.value(),
|
||||||
errorResponse = errorResponse,
|
errorResponse = errorResponse,
|
||||||
exception = e
|
exception = e
|
||||||
@ -68,7 +78,10 @@ class ExceptionControllerAdvice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [Exception::class])
|
@ExceptionHandler(value = [Exception::class])
|
||||||
fun handleException(e: Exception): ResponseEntity<CommonErrorResponse> {
|
fun handleException(
|
||||||
|
servletRequest: HttpServletRequest,
|
||||||
|
e: Exception
|
||||||
|
): ResponseEntity<CommonErrorResponse> {
|
||||||
log.error(e) { "[ExceptionControllerAdvice] Unexpected exception occurred: ${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
|
||||||
@ -77,6 +90,7 @@ class ExceptionControllerAdvice(
|
|||||||
|
|
||||||
logException(
|
logException(
|
||||||
type = LogType.UNHANDLED_EXCEPTION,
|
type = LogType.UNHANDLED_EXCEPTION,
|
||||||
|
servletRequest = servletRequest,
|
||||||
httpStatus = httpStatus.value(),
|
httpStatus = httpStatus.value(),
|
||||||
errorResponse = errorResponse,
|
errorResponse = errorResponse,
|
||||||
exception = e
|
exception = e
|
||||||
@ -89,12 +103,14 @@ class ExceptionControllerAdvice(
|
|||||||
|
|
||||||
private fun logException(
|
private fun logException(
|
||||||
type: LogType,
|
type: LogType,
|
||||||
|
servletRequest: HttpServletRequest,
|
||||||
httpStatus: Int,
|
httpStatus: Int,
|
||||||
errorResponse: CommonErrorResponse,
|
errorResponse: CommonErrorResponse,
|
||||||
exception: Exception
|
exception: Exception
|
||||||
) {
|
) {
|
||||||
val commonRequest = ConvertResponseMessageRequest(
|
val commonRequest = ConvertResponseMessageRequest(
|
||||||
type = type,
|
type = type,
|
||||||
|
endpoint = servletRequest.getEndpoint(),
|
||||||
httpStatus = httpStatus,
|
httpStatus = httpStatus,
|
||||||
startTime = MDC.get("startTime")?.toLongOrNull(),
|
startTime = MDC.get("startTime")?.toLongOrNull(),
|
||||||
body = errorResponse,
|
body = errorResponse,
|
||||||
|
|||||||
@ -45,6 +45,7 @@ class ApiLogMessageConverter(
|
|||||||
fun convertToResponseMessage(request: ConvertResponseMessageRequest): String {
|
fun convertToResponseMessage(request: ConvertResponseMessageRequest): String {
|
||||||
val payload: MutableMap<String, Any> = mutableMapOf()
|
val payload: MutableMap<String, Any> = mutableMapOf()
|
||||||
payload["type"] = request.type
|
payload["type"] = request.type
|
||||||
|
payload["endpoint"] = request.endpoint
|
||||||
payload["status_code"] = request.httpStatus
|
payload["status_code"] = request.httpStatus
|
||||||
|
|
||||||
MDC.get(MDC_MEMBER_ID_KEY)?.toLongOrNull()
|
MDC.get(MDC_MEMBER_ID_KEY)?.toLongOrNull()
|
||||||
@ -75,8 +76,11 @@ class ApiLogMessageConverter(
|
|||||||
|
|
||||||
data class ConvertResponseMessageRequest(
|
data class ConvertResponseMessageRequest(
|
||||||
val type: LogType,
|
val type: LogType,
|
||||||
|
val endpoint: String,
|
||||||
val httpStatus: Int = 200,
|
val httpStatus: Int = 200,
|
||||||
val startTime: Long? = null,
|
val startTime: Long? = null,
|
||||||
val body: Any? = null,
|
val body: Any? = null,
|
||||||
val exception: Exception? = null
|
val exception: Exception? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun HttpServletRequest.getEndpoint(): String = "${this.method} ${this.requestURI}"
|
||||||
|
|||||||
@ -33,22 +33,25 @@ class ControllerLoggingAspect(
|
|||||||
val startTime: Long = MDC.get("startTime").toLongOrNull() ?: System.currentTimeMillis()
|
val startTime: Long = MDC.get("startTime").toLongOrNull() ?: System.currentTimeMillis()
|
||||||
val controllerPayload: Map<String, Any> = parsePayload(joinPoint)
|
val controllerPayload: Map<String, Any> = parsePayload(joinPoint)
|
||||||
|
|
||||||
|
val servletRequest: HttpServletRequest = servletRequest()
|
||||||
|
|
||||||
log.info {
|
log.info {
|
||||||
messageConverter.convertToControllerInvokedMessage(servletRequest(), controllerPayload)
|
messageConverter.convertToControllerInvokedMessage(servletRequest, controllerPayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return joinPoint.proceed()
|
return joinPoint.proceed()
|
||||||
.also { logSuccess(startTime, it) }
|
.also { logSuccess(servletRequest.getEndpoint(), startTime, it) }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun logSuccess(startTime: Long, result: Any) {
|
private fun logSuccess(endpoint: String, startTime: Long, result: Any) {
|
||||||
val responseEntity = result as ResponseEntity<*>
|
val responseEntity = result as ResponseEntity<*>
|
||||||
var convertResponseMessageRequest = ConvertResponseMessageRequest(
|
var convertResponseMessageRequest = ConvertResponseMessageRequest(
|
||||||
type = LogType.CONTROLLER_SUCCESS,
|
type = LogType.CONTROLLER_SUCCESS,
|
||||||
|
endpoint = endpoint,
|
||||||
httpStatus = responseEntity.statusCode.value(),
|
httpStatus = responseEntity.statusCode.value(),
|
||||||
startTime = startTime,
|
startTime = startTime,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -50,14 +50,16 @@ class ApiLogMessageConverterTest : StringSpec({
|
|||||||
}
|
}
|
||||||
|
|
||||||
"Controller 응답 메시지를 반환한다." {
|
"Controller 응답 메시지를 반환한다." {
|
||||||
|
val endpoint = "POST /test/sangdol"
|
||||||
val request = ConvertResponseMessageRequest(
|
val request = ConvertResponseMessageRequest(
|
||||||
type = LogType.CONTROLLER_SUCCESS,
|
type = LogType.CONTROLLER_SUCCESS,
|
||||||
|
endpoint = endpoint,
|
||||||
httpStatus = 200,
|
httpStatus = 200,
|
||||||
exception = AuthException(AuthErrorCode.MEMBER_NOT_FOUND, "테스트 메시지!")
|
exception = AuthException(AuthErrorCode.MEMBER_NOT_FOUND, "테스트 메시지!")
|
||||||
)
|
)
|
||||||
|
|
||||||
converter.convertToResponseMessage(request) shouldBe """
|
converter.convertToResponseMessage(request) shouldBe """
|
||||||
{"type":"CONTROLLER_SUCCESS","status_code":200,"member_id":1,"exception":{"class":"AuthException","message":"테스트 메시지!"}}
|
{"type":"CONTROLLER_SUCCESS","endpoint":"$endpoint","status_code":200,"member_id":1,"exception":{"class":"AuthException","message":"테스트 메시지!"}}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user