diff --git a/src/main/kotlin/com/info/maeumgagym/application/domain/user/converter/RoleConverter.kt b/src/main/kotlin/com/info/maeumgagym/application/domain/user/converter/RoleConverter.kt index e709d2c3..abbcc457 100644 --- a/src/main/kotlin/com/info/maeumgagym/application/domain/user/converter/RoleConverter.kt +++ b/src/main/kotlin/com/info/maeumgagym/application/domain/user/converter/RoleConverter.kt @@ -22,7 +22,7 @@ internal class RoleConverter : AttributeConverter, String> { Role.USER.name -> Role.USER Role.ADMIN.name -> Role.ADMIN Role.SELLER.name -> Role.SELLER - else -> throw CriticalException(500, "Role Convert Error") + else -> throw CriticalException("Role Convert Error") } }.toMutableList() } diff --git a/src/main/kotlin/com/info/maeumgagym/common/exception/Exceptions.kt b/src/main/kotlin/com/info/maeumgagym/common/exception/Exceptions.kt index fffd96b8..34705739 100644 --- a/src/main/kotlin/com/info/maeumgagym/common/exception/Exceptions.kt +++ b/src/main/kotlin/com/info/maeumgagym/common/exception/Exceptions.kt @@ -2,6 +2,7 @@ package com.info.maeumgagym.common.exception import com.info.maeumgagym.common.annotation.responsibility.UseCase import com.info.maeumgagym.common.value.DomainNames +import org.springframework.http.HttpStatus /** * 마음가짐 내에서 전역적으로 쓰이는 예외 클래스의 최상위 타입 @@ -52,7 +53,8 @@ import com.info.maeumgagym.common.value.DomainNames */ open class MaeumGaGymException( val status: Int, - message: String + final override val message: String, + val responseMessage: String = message ) : RuntimeException(message) { companion object { @@ -77,8 +79,9 @@ open class MaeumGaGymException( */ class BusinessLogicException( status: Int, - message: String -) : MaeumGaGymException(status, message) { + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) { /** * [message] 표준화를 위해 도메인 이름과 Http 상태 코드 메세지를 이용해 [message]를 작성하는 생성자 @@ -145,8 +148,9 @@ class BusinessLogicException( */ class SecurityException( status: Int, - message: String -) : MaeumGaGymException(status, message) { + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) { constructor(errorCodePrefixSuffix: ErrorCodePrefixSuffix, domainName: DomainNames) : this( @@ -194,8 +198,9 @@ enum class ErrorCodePrefixSuffix( */ class FilterException( status: Int, - message: String -) : MaeumGaGymException(status, message) + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) /** * 인터셉터, 정확히는 커스텀 인터셉터 실행 중에 발생한 예외 @@ -204,21 +209,23 @@ class FilterException( */ class InterceptorException( status: Int, - message: String -) : MaeumGaGymException(status, message) + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) /** * 컨트롤러에서의 유효성 검증 과정 중 발생한 예외 * - * [ErrorLogResponseFilter]에서 Validation 실패시 발생하는 예외들을 이 예외로 변환 후 처리 + * [com.info.maeumgagym.infrastructure.error.filter.ErrorLogResponseFilter]에서 Validation 실패시 발생하는 예외들을 이 예외로 변환 후 처리 * * @see MaeumGaGymException */ class PresentationValidationException( status: Int, message: String, - val fields: Map -) : MaeumGaGymException(status, message) + val fields: Map, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) /** * SecurityFilterChain 실행 중에 발생한 예외 @@ -227,8 +234,9 @@ class PresentationValidationException( */ class AuthenticationException( status: Int, - message: String -) : MaeumGaGymException(status, message) { + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) { companion object { @@ -236,26 +244,36 @@ class AuthenticationException( val INVALID_TOKEN get() = AuthenticationException(401, "Invalid Token") val UNAUTHORIZED get() = AuthenticationException(401, "Unauthorized") val EXPIRED_TOKEN get() = AuthenticationException(401, "Expired Token") - val WRONG_USER_TOKEN get() = SecurityException(401, "Issued And User Mismatch, Cannot Use It") - val NOT_A_MAEUMGAGYM_TOKEN get() = SecurityException(401, "It's Not a MaeumGaGym Authentication Token") - val WRONG_TYPE_TOKEN get() = SecurityException(401, "Token Type Wrong, Not Supported") + val REVOKED_TOKEN + get() = AuthenticationException(401, "Revoked Token.", INVALID_TOKEN.responseMessage) + val WRONG_USER_TOKEN + get() = AuthenticationException( + 401, + "Issued And User Mismatch, Cannot Use It", + INVALID_TOKEN.responseMessage + ) + val NOT_A_MAEUMGAGYM_TOKEN + get() = AuthenticationException(401, "It's Not a MaeumGaGym Authentication Token. Invalid Prefix") + val WRONG_TYPE_TOKEN + get() = AuthenticationException(401, "Token Type Wrong, Not Supported", INVALID_TOKEN.responseMessage) // Forbidden - val ROLE_REQUIRED get() = AuthenticationException(403, "Role Required") + val ROLE_REQUIRED get() = AuthenticationException(403, "Role Required", FORBIDDEN.responseMessage) } } class FeignException( status: Int, - message: String -) : MaeumGaGymException(status, message) { + message: String, + responseMessage: String = message +) : MaeumGaGymException(status, message, responseMessage) { companion object { val FEIGN_BAD_REQUEST get() = FeignException(400, "Feign Bad Request") val FEIGN_UNAUTHORIZED get() = FeignException(401, "Feign UnAuthorized") val FEIGN_FORBIDDEN get() = FeignException(403, "Feign Forbidden") - val FEIGN_SERVER_ERROR get() = FeignException(500, "Feign Server Error") + val FEIGN_SERVER_ERROR get() = FeignException(500, "Feign Server Error", INTERNAL_SERVER_ERROR.responseMessage) val FEIGN_UNKNOWN_CLIENT_ERROR get() = FeignException(500, "Feign Unknown Error") } } @@ -266,6 +284,5 @@ class FeignException( * @see MaeumGaGymException */ class CriticalException( - status: Int, message: String -) : MaeumGaGymException(status, message) +) : MaeumGaGymException(HttpStatus.INTERNAL_SERVER_ERROR.value(), message, INTERNAL_SERVER_ERROR.responseMessage) diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ErrorLogResponseFilter.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ErrorLogResponseFilter.kt index ae8076ab..362790ca 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ErrorLogResponseFilter.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ErrorLogResponseFilter.kt @@ -1,7 +1,8 @@ package com.info.maeumgagym.infrastructure.error.filter import com.info.maeumgagym.common.exception.* -import com.info.maeumgagym.infrastructure.error.vo.ErrorLog +import com.info.maeumgagym.infrastructure.error.logger.ErrorLogger +import com.info.maeumgagym.infrastructure.error.vo.ErrorInfo import com.info.maeumgagym.infrastructure.response.writer.DefaultHttpServletResponseWriter import com.info.maeumgagym.infrastructure.response.writer.ErrorLogHttpServletResponseWriter import org.springframework.web.filter.OncePerRequestFilter @@ -14,12 +15,14 @@ import javax.servlet.http.HttpServletResponse * [Exception]이 발생했을 때, 응답 및 로그를 작성 * * [doFilter], 정확히는 [doFilterInternal]를 *try*문으로 감싸 실행. - * 이후 발생한 모든 예외를 *catch*해 각 예외에 따라 [ErrorLog]및 그에 대한 Response를 작성. + * 이후 발생한 모든 예외를 *catch*해 예외를 [ErrorInfo]로 가공하고, 로그 및 응답을 작성. + * [ErrorLogger]에서 로그를 작성하고, [ErrorLogHttpServletResponseWriter]에서 응답을 작성함. * * 원래 [DispatcherServlet][org.springframework.web.servlet.DispatcherServlet] 통과 이후 발생한 예외는 [NestedServletException.cause]로 감싸져 *throw*되지만, [ExceptionConvertFilter]에서 이를 [MaeumGaGymException]의 하위 타입으로 변환함. 자세한 것은 [ExceptionConvertFilter] 참조. * * 해당 *Filter*의 순서 설정 정보는 [ApplicationFilterChainConfig][com.info.maeumgagym.infrastructure.filter.config.ApplicationFilterChainConfig]에 존재 * + * @see ErrorLogger * @see ExceptionConvertFilter * @see ErrorLogHttpServletResponseWriter * @@ -28,7 +31,8 @@ import javax.servlet.http.HttpServletResponse */ class ErrorLogResponseFilter( private val defaultHttpServletResponseWriter: DefaultHttpServletResponseWriter, - private val errorLogHttpServletResponseWriter: ErrorLogHttpServletResponseWriter + private val errorLogHttpServletResponseWriter: ErrorLogHttpServletResponseWriter, + private val errorLogger: ErrorLogger ) : OncePerRequestFilter() { override fun doFilterInternal( @@ -39,47 +43,37 @@ class ErrorLogResponseFilter( try { filterChain.doFilter(request, response) } catch (e: MaeumGaGymException) { - resolveMaeumGaGymException(e, response) + resolveException(e, response) } catch (e: Exception) { - resolveUnknownException(e, response) + resolveException( + CriticalException("Unknown Type Exception Came to ${javaClass.name}").apply { initCause(e) }, + response + ) } } - private fun resolveMaeumGaGymException(e: MaeumGaGymException, response: HttpServletResponse) { - if (isOkStatus(e.status)) { + private fun resolveException(e: MaeumGaGymException, response: HttpServletResponse) { + if (isSuccessStatusCode(e.status)) { defaultHttpServletResponseWriter.doDefaultSettingWithStatusCode(response, e.status) return } - val errorLog = printErrorLogAndReturn(e) + val errorInfo = ErrorInfo.of(e) if (isUnknownMaeumGaGymException(e)) { e.printStackTrace() } - errorLogHttpServletResponseWriter.writeResponseWithErrorLog(response, errorLog) - } - - private fun resolveUnknownException(e: Exception, response: HttpServletResponse) { - val errorLog = printErrorLogAndReturn(e) - - e.printStackTrace() + errorLogHttpServletResponseWriter.writeErrorResponse(response, errorInfo) - errorLogHttpServletResponseWriter.writeResponseWithErrorLog(response, errorLog) + errorLogger.printLog(errorInfo) } - private fun isOkStatus(status: Int): Boolean = + private fun isSuccessStatusCode(status: Int): Boolean = status in 200..299 private fun isUnknownMaeumGaGymException(e: MaeumGaGymException): Boolean = e !is BusinessLogicException && e !is SecurityException && e !is FilterException && e !is InterceptorException && e !is AuthenticationException && e !is PresentationValidationException - - private fun printErrorLogAndReturn(e: Exception): ErrorLog { - ErrorLog.of(e).run { - logger.info(this.toString()) - return this - } - } } diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ExceptionConvertFilter.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ExceptionConvertFilter.kt index a074877d..00570470 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ExceptionConvertFilter.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/filter/ExceptionConvertFilter.kt @@ -2,6 +2,7 @@ package com.info.maeumgagym.infrastructure.error.filter import com.info.maeumgagym.common.exception.MaeumGaGymException import com.info.maeumgagym.common.exception.PresentationValidationException +import com.info.maeumgagym.infrastructure.error.repository.ExceptionRepository import org.springframework.web.bind.MethodArgumentNotValidException import org.springframework.web.bind.MissingServletRequestParameterException import org.springframework.web.filter.GenericFilterBean @@ -25,7 +26,7 @@ import javax.validation.ConstraintViolationException * ``` * - [MaeumGaGymException] 및 그 하위 타입일 경우 [MaeumGaGymException]으로 변환. * - Presentation 계층에서 Validation이 실패했을 경우 발생하는 예외 중 하나일 경우 [PresentationValidationException]으로 변환; 변환되는 타입 : [MethodArgumentNotValidException], [ConstraintViolationException], [MissingServletRequestParameterException] - * - 그 외에는 그대로 변환 + * - 그 외에는 일반 [MaeumGaGymException]으로 감싸짐 * * 해당 *Filter*의 순서 설정 정보는 [ApplicationFilterChainConfig][com.info.maeumgagym.infrastructure.filter.config.ApplicationFilterChainConfig]에 존재 * @@ -35,13 +36,15 @@ import javax.validation.ConstraintViolationException * @since 22.02.2024 */ class ExceptionConvertFilter( - private val exceptionRepository: com.info.maeumgagym.infrastructure.error.repository.ExceptionRepository + private val exceptionRepository: ExceptionRepository ) : GenericFilterBean() { override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) { try { chain.doFilter(request, response) exceptionRepository.throwIt() + } catch (e: MaeumGaGymException) { + throw e } catch (e: NestedServletException) { throw when (e.cause) { is MaeumGaGymException -> e.cause as MaeumGaGymException @@ -52,7 +55,7 @@ class ExceptionConvertFilter( 400, "field : ${fieldError?.field}\nparameter : $parameter", mapOf() - ) + ).apply { initCause(e) } } is ConstraintViolationException -> @@ -63,7 +66,7 @@ class ExceptionConvertFilter( fields = constraintViolations.associate { Pair(it.propertyPath.toString(), it.message) } - ) + ).apply { initCause(e) } } is MissingServletRequestParameterException -> @@ -72,7 +75,7 @@ class ExceptionConvertFilter( status = 400, message = message, fields = mapOf(Pair(parameterName, localizedMessage)) - ) + ).apply { initCause(e) } } else -> e.cause ?: e @@ -82,7 +85,13 @@ class ExceptionConvertFilter( status = 400, message = "DateTime Format Wrong", fields = mapOf() - ) + ).apply { initCause(e) } + } catch (e: Exception) { + throw MaeumGaGymException( + 500, + e.message ?: e.localizedMessage ?: ("Cause Exception Class : " + e.javaClass.name), + MaeumGaGymException.INTERNAL_SERVER_ERROR.responseMessage + ).apply { initCause(e) } } } } diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLogger.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLogger.kt new file mode 100644 index 00000000..1a2c64c7 --- /dev/null +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLogger.kt @@ -0,0 +1,14 @@ +package com.info.maeumgagym.infrastructure.error.logger + +import com.info.maeumgagym.infrastructure.error.vo.ErrorInfo + +/** + * [ErrorInfo]를 로그로 출력 + * + * @author Daybreak312 + * @since 09-05-2024 + */ +interface ErrorLogger { + + fun printLog(errorInfo: ErrorInfo) +} diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLoggerImpl.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLoggerImpl.kt new file mode 100644 index 00000000..85e221af --- /dev/null +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/logger/ErrorLoggerImpl.kt @@ -0,0 +1,27 @@ +package com.info.maeumgagym.infrastructure.error.logger + +import com.info.maeumgagym.infrastructure.error.vo.ErrorInfo +import org.apache.commons.logging.LogFactory +import org.springframework.stereotype.Component + +@Component +class ErrorLoggerImpl : ErrorLogger { + + private val logger = LogFactory.getLog(javaClass) + + override fun printLog(errorInfo: ErrorInfo) { + errorInfo.run { + logger.warn( + "[$id] $status : \"$message\" with exception \"$exceptionClassName\"" + ) + + logger.warn( + "\tat ${errorOccurredClassName.first()}" + ) + + errorOccurredClassName.subList(1, errorOccurredClassName.size).forEach { + logger.warn("\t or $it") + } + } + } +} diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorLog.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorInfo.kt similarity index 53% rename from src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorLog.kt rename to src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorInfo.kt index 00288b30..b8211e59 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorLog.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorInfo.kt @@ -5,56 +5,55 @@ import com.info.maeumgagym.common.exception.PresentationValidationException import java.time.LocalDateTime import java.util.* -data class ErrorLog( +data class ErrorInfo( val id: String = UUID.randomUUID().toString().substring(0 until 7), val exceptionClassName: String, - val errorOccurredClassName: String, + val errorOccurredClassName: List, val status: Int = 500, - val message: String? = null, + val message: String, + val responseMessage: String, val map: Map = mapOf(), val timestamp: LocalDateTime = LocalDateTime.now() ) { companion object { - fun of(e: Exception) = + fun of(e: MaeumGaGymException) = when (e) { is PresentationValidationException -> e.run { - ErrorLog( + ErrorInfo( exceptionClassName = javaClass.name, - errorOccurredClassName = getErrorOccurredClassName( - stackTrace.toList() - ), + errorOccurredClassName = getErrorOccurredClassName(stackTrace.toList()), status = status, message = message, + responseMessage = responseMessage, map = fields ) } - is MaeumGaGymException -> e.run { - ErrorLog( - exceptionClassName = javaClass.name, - errorOccurredClassName = getErrorOccurredClassName( - stackTrace.toList() - ), - status = status, - message = message - ) - } - else -> e.run { - ErrorLog( + ErrorInfo( exceptionClassName = javaClass.name, - errorOccurredClassName = getErrorOccurredClassName( - stackTrace.toList() - ), - message = message + errorOccurredClassName = getErrorOccurredClassName(stackTrace.toList()), + status = status, + message = message, + responseMessage = responseMessage ) } } } - - override fun toString() = - "[$id] $status : \"$message\" in > $errorOccurredClassName < cause \"$exceptionClassName\"" } -private fun getErrorOccurredClassName(stackTrace: List): String = - "\"${stackTrace[3].className}\" or \"${stackTrace[2].className}\" or \"${stackTrace[1].className}\"" +private fun getErrorOccurredClassName(stackTrace: List): List { + if (stackTrace.size < 5) { + return stackTrace.map { it.className } + } + + val classes = mutableSetOf() + + var i = 0 + while (classes.size != 5) { + classes.add(stackTrace[i].className) + i++ + } + + return classes.toList() +} diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorResponse.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorResponse.kt deleted file mode 100644 index 3321ad83..00000000 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/error/vo/ErrorResponse.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.info.maeumgagym.infrastructure.error.vo - -data class ErrorResponse( - val status: Int, - val message: String -) diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/chained/ChainedFilterChain.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/chained/ChainedFilterChain.kt index 13051552..24d44e25 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/chained/ChainedFilterChain.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/chained/ChainedFilterChain.kt @@ -70,7 +70,7 @@ abstract class ChainedFilterChain : GlobalFilterChain { */ final override fun doFilter(request: ServletRequest, response: ServletResponse) { if (calledFilterChain.get() == null) { - throw CriticalException(500, "ChainedFilterChain called with doesn't init CalledFilterChain") + throw CriticalException("ChainedFilterChain called with doesn't init CalledFilterChain") } plusCurrentFilterIndex() diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/config/ApplicationFilterChainConfig.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/config/ApplicationFilterChainConfig.kt index 0ed1f870..462dff83 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/config/ApplicationFilterChainConfig.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/filter/config/ApplicationFilterChainConfig.kt @@ -5,6 +5,7 @@ import com.info.maeumgagym.infrastructure.error.filter.ErrorLogResponseFilter import com.info.maeumgagym.infrastructure.error.filter.ExceptionConvertFilter import com.info.maeumgagym.infrastructure.error.filter.filterchain.ExceptionChainedFilterChain import com.info.maeumgagym.infrastructure.error.filter.filterchain.ExceptionChainedFilterChainProxy +import com.info.maeumgagym.infrastructure.error.logger.ErrorLogger import com.info.maeumgagym.infrastructure.error.repository.ExceptionRepository import com.info.maeumgagym.infrastructure.request.context.CurrentRequestContext import com.info.maeumgagym.infrastructure.request.filter.CurrentRequestContextFilter @@ -21,7 +22,6 @@ import org.springframework.context.annotation.Configuration import org.springframework.web.filter.CharacterEncodingFilter import org.springframework.web.filter.DelegatingFilterProxy import javax.servlet.Filter -import javax.servlet.ServletContext /** * [ApplicationFilterChain][org.apache.catalina.core.ApplicationFilterChain] 속 Filter들의 삽입과 순서 설정 @@ -35,10 +35,10 @@ import javax.servlet.ServletContext class ApplicationFilterChainConfig( private val defaultHttpServletResponseWriter: DefaultHttpServletResponseWriter, private val errorLogHttpServletResponseWriter: ErrorLogHttpServletResponseWriter, + private val errorLogger: ErrorLogger, private val exceptionRepository: ExceptionRepository, private val currentRequestContext: CurrentRequestContext, - private val applicationContext: ApplicationContext, - private val servletContext: ServletContext + private val applicationContext: ApplicationContext ) { /** @@ -99,7 +99,8 @@ class ApplicationFilterChainConfig( ErrorLogResponseFilter::class.simpleName!!, ErrorLogResponseFilter( defaultHttpServletResponseWriter, - errorLogHttpServletResponseWriter + errorLogHttpServletResponseWriter, + errorLogger ) ), Pair( @@ -152,7 +153,7 @@ class ApplicationFilterChainConfig( val index = this.filtersOrderList.indexOf(`class`) if (index == -1) { - throw CriticalException(500, "Attempted registration of Unknown filter") + throw CriticalException("Attempted registration of Unknown filter") } return index + Int.MIN_VALUE diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/ErrorLogHttpServletResponseWriter.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/ErrorLogHttpServletResponseWriter.kt index ca5109ce..89fcb0d8 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/ErrorLogHttpServletResponseWriter.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/ErrorLogHttpServletResponseWriter.kt @@ -1,12 +1,11 @@ package com.info.maeumgagym.infrastructure.response.writer -import com.info.maeumgagym.common.exception.MaeumGaGymException -import com.info.maeumgagym.infrastructure.error.vo.ErrorLog +import com.info.maeumgagym.infrastructure.error.vo.ErrorInfo import java.time.LocalDateTime import javax.servlet.http.HttpServletResponse /** - * [ErrorLog]의 정보로 [HttpServletResponse]를 작성하기 위한 [HttpServletResponseWriter] + * [ErrorInfo]의 정보로 [HttpServletResponse]를 작성하기 위한 [HttpServletResponseWriter] * * [DefaultHttpServletResponseWriter]를 내부 변수로 갖고 있어, [setBody]와 [doDefaultSettingWithStatusCode]는 [DefaultHttpServletResponseWriter]를 통해 Proxy 형태로 구현됨. * @@ -37,7 +36,7 @@ abstract class ErrorLogHttpServletResponseWriter : HttpServletResponseWriter { ): HttpServletResponse /** - * 인자로 받은 [ErrorLog]의 정보를 기반으로 [HttpServletResponse]를 작성. + * 인자로 받은 [ErrorInfo]의 정보를 기반으로 [HttpServletResponse]를 작성. * * 사용되는 정보는 [ErrorLogResponse]의 Docs 참고. * @@ -46,9 +45,9 @@ abstract class ErrorLogHttpServletResponseWriter : HttpServletResponseWriter { * @author Daybreak312 * @since 12-03-2024 */ - abstract fun writeResponseWithErrorLog( + abstract fun writeErrorResponse( response: HttpServletResponse, - errorLog: ErrorLog + errorInfo: ErrorInfo ): HttpServletResponse } @@ -70,27 +69,4 @@ data class ErrorLogResponse( val errorLogId: String, val timestamp: LocalDateTime = LocalDateTime.now(), val map: Map = mapOf() -) { - - companion object { - fun of(errorLog: ErrorLog): ErrorLogResponse = - errorLog.run { - ErrorLogResponse( - status = status, - message = errorLog.getErrorResponseMessage(), - errorLogId = id, - timestamp = timestamp, - map = map - ) - } - } -} - -private fun ErrorLog.getErrorResponseMessage(): String = - if (isServerErrorStatus(this.status)) { - MaeumGaGymException.INTERNAL_SERVER_ERROR.message!! - } else { - this.message ?: "" - } - -private fun isServerErrorStatus(status: Int): Boolean = status in 500..599 +) diff --git a/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/impl/ErrorLogHttpServletResponseWriterImpl.kt b/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/impl/ErrorLogHttpServletResponseWriterImpl.kt index b9b8d31a..e70738f2 100644 --- a/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/impl/ErrorLogHttpServletResponseWriterImpl.kt +++ b/src/main/kotlin/com/info/maeumgagym/infrastructure/response/writer/impl/ErrorLogHttpServletResponseWriterImpl.kt @@ -1,6 +1,6 @@ package com.info.maeumgagym.infrastructure.response.writer.impl -import com.info.maeumgagym.infrastructure.error.vo.ErrorLog +import com.info.maeumgagym.infrastructure.error.vo.ErrorInfo import com.info.maeumgagym.infrastructure.response.writer.DefaultHttpServletResponseWriter import com.info.maeumgagym.infrastructure.response.writer.ErrorLogHttpServletResponseWriter import com.info.maeumgagym.infrastructure.response.writer.ErrorLogResponse @@ -27,14 +27,20 @@ private class ErrorLogHttpServletResponseWriterImpl( ): HttpServletResponse = defaultHttpServletResponseWriter.doDefaultSettingWithStatusCode(response, status) - override fun writeResponseWithErrorLog( + override fun writeErrorResponse( response: HttpServletResponse, - errorLog: ErrorLog + errorInfo: ErrorInfo ): HttpServletResponse = response.apply { - doDefaultSettingWithStatusCode(response, errorLog.status) + doDefaultSettingWithStatusCode(response, errorInfo.status) setBody( response = response, - `object` = ErrorLogResponse.of(errorLog) + `object` = ErrorLogResponse( + status = status, + message = errorInfo.responseMessage, + errorLogId = errorInfo.id, + timestamp = errorInfo.timestamp, + map = errorInfo.map + ) ) } } diff --git a/src/main/kotlin/com/info/maeumgagym/security/authentication/provider/impl/UserModelAuthenticationProviderImpl.kt b/src/main/kotlin/com/info/maeumgagym/security/authentication/provider/impl/UserModelAuthenticationProviderImpl.kt index 2e0a7b76..3172c65b 100644 --- a/src/main/kotlin/com/info/maeumgagym/security/authentication/provider/impl/UserModelAuthenticationProviderImpl.kt +++ b/src/main/kotlin/com/info/maeumgagym/security/authentication/provider/impl/UserModelAuthenticationProviderImpl.kt @@ -19,7 +19,6 @@ class UserModelAuthenticationProviderImpl( userSubject = subject, user = readUserPort.readByOAuthId(subject) ?: throw CriticalException( - 500, "User Not Found with Subject in AccessToken at ${this::class.simpleName}" ) ) diff --git a/src/main/kotlin/com/info/maeumgagym/security/authentication/vo/UserModelAuthentication.kt b/src/main/kotlin/com/info/maeumgagym/security/authentication/vo/UserModelAuthentication.kt index 57fa8138..47324853 100644 --- a/src/main/kotlin/com/info/maeumgagym/security/authentication/vo/UserModelAuthentication.kt +++ b/src/main/kotlin/com/info/maeumgagym/security/authentication/vo/UserModelAuthentication.kt @@ -21,7 +21,7 @@ class UserModelAuthentication( */ init { if (user != null && user.oauthId != userSubject) { - throw CriticalException(500, "user's subject and userSubject are different") + throw CriticalException("user's subject and userSubject are different") } } @@ -63,7 +63,7 @@ class UserModelAuthentication( */ override fun setAuthenticated(isAuthenticated: Boolean) { if (!isAuthenticated) { - throw CriticalException(500, "UserModelAuthentication MUSE BE Authenticated.") + throw CriticalException("UserModelAuthentication MUSE BE Authenticated.") } } } diff --git a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenAdapter.kt b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenAdapter.kt index fd4a8ca7..426c7c52 100644 --- a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenAdapter.kt +++ b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenAdapter.kt @@ -45,7 +45,7 @@ class MaeumgagymTokenAdapter( override fun revoke(token: String?) { val decoded = if (token == null) { maeumgagymTokenContext.getCurrentToken() - ?: throw CriticalException(500, "Token is NULL In Revoke(Only Authenticated Can Access)") + ?: throw CriticalException("Token is NULL In Revoke(Only Authenticated Can Access)") } else { maeumgagymTokenDecoder.decode(token) } diff --git a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenDecoderImpl.kt b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenDecoderImpl.kt index cf60b6c3..4cc8651d 100644 --- a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenDecoderImpl.kt +++ b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenDecoderImpl.kt @@ -28,9 +28,13 @@ internal class MaeumgagymTokenDecoderImpl( } override fun decode(token: String, key: String): MaeumgagymToken { - val decrypted = decrypt.decrypt(resolveTokenPrefix(token), key) + try { + val decrypted = decrypt.decrypt(resolveTokenPrefix(token), key) - return stringTokenToVO(decrypted) + return stringTokenToVO(decrypted) + } catch (e: Exception) { + throw AuthenticationException.INVALID_TOKEN + } } private fun resolveTokenPrefix(token: String): String { diff --git a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenValidatorImpl.kt b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenValidatorImpl.kt index 8cc4fef1..357e639d 100644 --- a/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenValidatorImpl.kt +++ b/src/main/kotlin/com/info/maeumgagym/security/mgtoken/impl/MaeumgagymTokenValidatorImpl.kt @@ -25,7 +25,7 @@ internal class MaeumgagymTokenValidatorImpl( override fun validate(maeumgagymToken: MaeumgagymToken) { if (revokedMGTokenContext.checkRevoked(maeumgagymToken.tokenId)) { - throw AuthenticationException.INVALID_TOKEN + throw AuthenticationException.REVOKED_TOKEN } when (maeumgagymToken.type) {