@@ -3,11 +3,12 @@ package nexters.tuk.ui
33import com.fasterxml.jackson.databind.JsonMappingException
44import com.fasterxml.jackson.databind.exc.InvalidFormatException
55import com.fasterxml.jackson.databind.exc.MismatchedInputException
6+ import jakarta.servlet.http.HttpServletRequest
7+ import nexters.tuk.application.alert.ApiErrorAlert
8+ import nexters.tuk.application.alert.ApiErrorAlertSender
69import nexters.tuk.contract.ApiResponse
710import nexters.tuk.contract.BaseException
811import nexters.tuk.contract.ErrorType
9- import nexters.tuk.application.alert.ApiErrorAlert
10- import nexters.tuk.application.alert.ApiErrorAlertSender
1112import org.slf4j.LoggerFactory
1213import org.springframework.http.ResponseEntity
1314import org.springframework.http.converter.HttpMessageNotReadableException
@@ -16,7 +17,6 @@ import org.springframework.web.bind.annotation.RestControllerAdvice
1617import org.springframework.web.server.MissingRequestValueException
1718import org.springframework.web.server.ServerWebInputException
1819import org.springframework.web.servlet.resource.NoResourceFoundException
19- import jakarta.servlet.http.HttpServletRequest
2020import java.time.ZonedDateTime
2121
2222@RestControllerAdvice
@@ -28,33 +28,46 @@ class ApiControllerAdvice(
2828 @ExceptionHandler
2929 fun handle (e : BaseException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
3030 log.warn(" BaseException : {}" , e.message, e)
31- return failureResponse(request, e.errorType, e.message)
31+ sendErrorAlert(request, e.errorType, e.message)
32+ return failureResponse(e.errorType, e.message)
3233 }
3334
3435 @ExceptionHandler
35- fun handle (e : IllegalArgumentException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
36+ fun handle (
37+ e : IllegalArgumentException ,
38+ request : HttpServletRequest
39+ ): ResponseEntity <ApiResponse <* >> {
3640 log.warn(" BaseException : {}" , e.message, e)
37- return failureResponse(request, ErrorType .BAD_REQUEST , e.message)
41+ sendErrorAlert(request, ErrorType .BAD_REQUEST , e.message)
42+ return failureResponse(ErrorType .BAD_REQUEST , e.message)
3843 }
3944
4045 @ExceptionHandler
41- fun handle (e : MissingRequestValueException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
46+ fun handle (
47+ e : MissingRequestValueException ,
48+ request : HttpServletRequest
49+ ): ResponseEntity <ApiResponse <* >> {
4250 val name = e.methodParameter?.parameter?.name
4351 val type = e.methodParameter?.parameter?.type?.simpleName
4452 val message = " 필수 요청 파라미터 '$name ' (타입: $type )가 누락되었습니다."
45- return failureResponse(request, ErrorType .BAD_REQUEST , message)
53+ sendErrorAlert(request, ErrorType .BAD_REQUEST , message)
54+ return failureResponse(ErrorType .BAD_REQUEST , message)
4655 }
4756
4857 @ExceptionHandler
49- fun handle (e : HttpMessageNotReadableException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
58+ fun handle (
59+ e : HttpMessageNotReadableException ,
60+ request : HttpServletRequest
61+ ): ResponseEntity <ApiResponse <* >> {
5062 val errorMessage = when (val rootCause = e.rootCause) {
5163 is InvalidFormatException -> {
5264 val fieldName = rootCause.path.joinToString(" ." ) { it.fieldName ? : " ?" }
5365
5466 val valueIndicationMessage = when {
5567 rootCause.targetType.isEnum -> {
5668 val enumClass = rootCause.targetType
57- val enumValues = enumClass.enumConstants.joinToString(" , " ) { it.toString() }
69+ val enumValues =
70+ enumClass.enumConstants.joinToString(" , " ) { it.toString() }
5871 " 사용 가능한 값 : [$enumValues ]"
5972 }
6073
@@ -80,19 +93,24 @@ class ApiControllerAdvice(
8093 else -> " 요청 본문을 처리하는 중 오류가 발생했습니다. JSON 메세지 규격을 확인해주세요."
8194 }
8295
83- return failureResponse(request, ErrorType .BAD_REQUEST , errorMessage)
96+ sendErrorAlert(request, ErrorType .BAD_REQUEST , errorMessage)
97+ return failureResponse(ErrorType .BAD_REQUEST , errorMessage)
8498 }
8599
86100 @ExceptionHandler
87- fun handleBadRequest (e : ServerWebInputException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
101+ fun handleBadRequest (
102+ e : ServerWebInputException ,
103+ request : HttpServletRequest
104+ ): ResponseEntity <ApiResponse <* >> {
88105 val errorMessage = when (val rootCause = e.rootCause) {
89106 is InvalidFormatException -> {
90107 val fieldName = rootCause.path.joinToString(" ." ) { it.fieldName ? : " ?" }
91108
92109 val valueIndicationMessage = when {
93110 rootCause.targetType.isEnum -> {
94111 val enumClass = rootCause.targetType
95- val enumValues = enumClass.enumConstants.joinToString(" , " ) { it.toString() }
112+ val enumValues =
113+ enumClass.enumConstants.joinToString(" , " ) { it.toString() }
96114 " 사용 가능한 값 : [$enumValues ]"
97115 }
98116
@@ -120,27 +138,56 @@ class ApiControllerAdvice(
120138 else -> " 요청 본문을 처리하는 중 오류가 발생했습니다. JSON 메세지 규격을 확인해주세요."
121139 }
122140
123- return failureResponse(request, ErrorType .BAD_REQUEST , errorMessage)
141+ sendErrorAlert(request, ErrorType .BAD_REQUEST , errorMessage)
142+ return failureResponse(ErrorType .BAD_REQUEST , errorMessage)
124143 }
125144
126145 @ExceptionHandler
127- fun handleNotFound (e : NoResourceFoundException , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
146+ fun handleNotFound (
147+ e : NoResourceFoundException ,
148+ request : HttpServletRequest
149+ ): ResponseEntity <ApiResponse <* >> {
128150 val message = " 리소스를 찾을 수 없습니다: ${request.requestURI} "
129- return failureResponse(request, ErrorType .NOT_FOUND , message)
151+ return ResponseEntity (
152+ ApiResponse .fail(errorType = ErrorType .NOT_FOUND , errorMessage = message),
153+ ErrorType .NOT_FOUND .status,
154+ )
130155 }
131156
132157 @ExceptionHandler
133158 fun handle (e : Throwable , request : HttpServletRequest ): ResponseEntity <ApiResponse <* >> {
134159 log.error(" Exception : {}" , e.message, e)
135160 val message = e.message ? : " 알 수 없는 서버 오류가 발생했습니다"
136- return failureResponse(request, ErrorType .INTERNAL_ERROR , message)
161+ sendErrorAlert(request, ErrorType .INTERNAL_ERROR , message)
162+ return failureResponse(ErrorType .INTERNAL_ERROR , message)
137163 }
138164
139- private fun failureResponse (request : HttpServletRequest , errorType : ErrorType , errorMessage : String? = null): ResponseEntity <ApiResponse <* >> {
140- errorAlertSender.sendError(ApiErrorAlert (errorType.status.value(), request.method, request.requestURI, ZonedDateTime .now(), errorMessage ? : errorType.message))
165+ private fun failureResponse (
166+ errorType : ErrorType ,
167+ errorMessage : String? = null
168+ ): ResponseEntity <ApiResponse <* >> {
141169 return ResponseEntity (
142- ApiResponse .fail(errorType = errorType, errorMessage = errorMessage ? : errorType.message),
170+ ApiResponse .fail(
171+ errorType = errorType,
172+ errorMessage = errorMessage ? : errorType.message
173+ ),
143174 errorType.status,
144175 )
145176 }
177+
178+ private fun sendErrorAlert (
179+ request : HttpServletRequest ,
180+ errorType : ErrorType ,
181+ errorMessage : String? = null
182+ ) {
183+ errorAlertSender.sendError(
184+ ApiErrorAlert (
185+ errorType.status.value(),
186+ request.method,
187+ request.requestURI,
188+ ZonedDateTime .now(),
189+ errorMessage ? : errorType.message
190+ )
191+ )
192+ }
146193}
0 commit comments