From 93ab801562367c07d003cabbd08c864ea7af9e8a Mon Sep 17 00:00:00 2001 From: devxb Date: Mon, 30 Dec 2024 22:59:20 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EA=B8=B8=EB=93=9C=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=A4=91=20=EC=97=90=EB=9F=AC=EB=B0=9C=EC=83=9D=EC=8B=9C=20?= =?UTF-8?q?=EB=AC=B4=ED=95=9C=EB=A1=9C=EB=94=A9=20=ED=98=84=EC=83=81=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- .../{render/app => core}/Exception.kt | 4 ++- .../guild/controller/GuildController.kt | 17 ++++++++++ .../controller/response/ErrorResponse.kt | 11 +++++++ .../guild/infra/HttpClientConfigurer.kt | 31 ++++++++++++++++--- .../guild/infra/HttpClientErrorHandler.kt | 28 +++++++++++++++++ .../render/controller/BackgroundController.kt | 5 +++ .../controller/InternalPersonaController.kt | 2 +- .../render/controller/PersonaController.kt | 7 ++++- .../render/infra/RestIdentityApi.kt | 2 +- 10 files changed, 100 insertions(+), 9 deletions(-) rename src/main/kotlin/org/gitanimals/{render/app => core}/Exception.kt (54%) create mode 100644 src/main/kotlin/org/gitanimals/guild/controller/response/ErrorResponse.kt create mode 100644 src/main/kotlin/org/gitanimals/guild/infra/HttpClientErrorHandler.kt diff --git a/gradle.properties b/gradle.properties index 3563473..5cbd249 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,7 +24,7 @@ kotestExtensionSpringVersion=1.1.3 testContainerVersion=1.19.3 ### Netx ### -netxVersion=0.4.7 +netxVersion=0.4.8 ### Sentry ### sentryVersion=4.4.0 diff --git a/src/main/kotlin/org/gitanimals/render/app/Exception.kt b/src/main/kotlin/org/gitanimals/core/Exception.kt similarity index 54% rename from src/main/kotlin/org/gitanimals/render/app/Exception.kt rename to src/main/kotlin/org/gitanimals/core/Exception.kt index d0eae82..4299fcf 100644 --- a/src/main/kotlin/org/gitanimals/render/app/Exception.kt +++ b/src/main/kotlin/org/gitanimals/core/Exception.kt @@ -1,6 +1,8 @@ -package org.gitanimals.render.app +package org.gitanimals.core +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +@JsonIgnoreProperties(ignoreUnknown = true) class AuthorizationException(message: String) : IllegalArgumentException(message) val AUTHORIZATION_EXCEPTION = AuthorizationException("Authorization fail") diff --git a/src/main/kotlin/org/gitanimals/guild/controller/GuildController.kt b/src/main/kotlin/org/gitanimals/guild/controller/GuildController.kt index 85d2c74..54575e3 100644 --- a/src/main/kotlin/org/gitanimals/guild/controller/GuildController.kt +++ b/src/main/kotlin/org/gitanimals/guild/controller/GuildController.kt @@ -1,5 +1,6 @@ package org.gitanimals.guild.controller +import org.gitanimals.core.AuthorizationException import org.gitanimals.core.FieldType import org.gitanimals.guild.app.* import org.gitanimals.guild.app.request.CreateGuildRequest @@ -10,6 +11,7 @@ import org.gitanimals.guild.domain.GuildService import org.gitanimals.guild.domain.SearchFilter import org.gitanimals.guild.domain.extension.GuildFieldTypeExtension.isGuildField import org.gitanimals.guild.domain.request.ChangeGuildRequest +import org.gitanimals.guild.controller.response.ErrorResponse import org.springframework.http.HttpHeaders import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @@ -146,4 +148,19 @@ class GuildController( fun draw( @PathVariable("guildId") guildId: Long, ) = drawGuildFacade.drawGuild(guildId) + + @ExceptionHandler(IllegalArgumentException::class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + fun handleIllegalArgumentException(exception: IllegalArgumentException): ErrorResponse = + ErrorResponse.from(exception) + + @ExceptionHandler(IllegalStateException::class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + fun handleIllegalArgumentException(exception: IllegalStateException): ErrorResponse = + ErrorResponse.from(exception) + + @ExceptionHandler(AuthorizationException::class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + fun handleAuthorizationException(exception: AuthorizationException): ErrorResponse = + ErrorResponse.from(exception) } diff --git a/src/main/kotlin/org/gitanimals/guild/controller/response/ErrorResponse.kt b/src/main/kotlin/org/gitanimals/guild/controller/response/ErrorResponse.kt new file mode 100644 index 0000000..c798c86 --- /dev/null +++ b/src/main/kotlin/org/gitanimals/guild/controller/response/ErrorResponse.kt @@ -0,0 +1,11 @@ +package org.gitanimals.guild.controller.response + +data class ErrorResponse( + val message: String, +) { + + companion object { + fun from(exception: Exception): ErrorResponse = + ErrorResponse(exception.message ?: exception.localizedMessage) + } +} diff --git a/src/main/kotlin/org/gitanimals/guild/infra/HttpClientConfigurer.kt b/src/main/kotlin/org/gitanimals/guild/infra/HttpClientConfigurer.kt index 8a04a17..e818028 100644 --- a/src/main/kotlin/org/gitanimals/guild/infra/HttpClientConfigurer.kt +++ b/src/main/kotlin/org/gitanimals/guild/infra/HttpClientConfigurer.kt @@ -15,7 +15,11 @@ class HttpClientConfigurer { @Bean fun identityApiHttpClient(): IdentityApi { - val restClient = RestClient.create("https://api.gitanimals.org") + val restClient = RestClient + .builder() + .defaultStatusHandler(httpClientErrorHandler()) + .baseUrl("https://api.gitanimals.org") + .build() val httpServiceProxyFactory = HttpServiceProxyFactory .builderFor(RestClientAdapter.create(restClient)) @@ -26,7 +30,11 @@ class HttpClientConfigurer { @Bean fun renderApiHttpClient(): RenderApi { - val restClient = RestClient.create("https://render.gitanimals.org") + val restClient = RestClient + .builder() + .defaultStatusHandler(httpClientErrorHandler()) + .baseUrl("https://render.gitanimals.org") + .build() val httpServiceProxyFactory = HttpServiceProxyFactory .builderFor(RestClientAdapter.create(restClient)) @@ -34,6 +42,9 @@ class HttpClientConfigurer { return httpServiceProxyFactory.createClient(RenderApi::class.java) } + + @Bean + fun httpClientErrorHandler(): HttpClientErrorHandler = HttpClientErrorHandler() } @Configuration @@ -42,7 +53,11 @@ class TestHttpClientConfigurer { @Bean fun identityApiHttpClient(): IdentityApi { - val restClient = RestClient.create("http://localhost:8080") + val restClient = RestClient + .builder() + .defaultStatusHandler(httpClientErrorHandler()) + .baseUrl("http://localhost:8080") + .build() val httpServiceProxyFactory = HttpServiceProxyFactory .builderFor(RestClientAdapter.create(restClient)) @@ -53,7 +68,11 @@ class TestHttpClientConfigurer { @Bean fun renderApiHttpClient(): RenderApi { - val restClient = RestClient.create("http://localhost:8080") + val restClient = RestClient + .builder() + .defaultStatusHandler(httpClientErrorHandler()) + .baseUrl("http://localhost:8080") + .build() val httpServiceProxyFactory = HttpServiceProxyFactory .builderFor(RestClientAdapter.create(restClient)) @@ -61,4 +80,8 @@ class TestHttpClientConfigurer { return httpServiceProxyFactory.createClient(RenderApi::class.java) } + + + @Bean + fun httpClientErrorHandler(): HttpClientErrorHandler = HttpClientErrorHandler() } diff --git a/src/main/kotlin/org/gitanimals/guild/infra/HttpClientErrorHandler.kt b/src/main/kotlin/org/gitanimals/guild/infra/HttpClientErrorHandler.kt new file mode 100644 index 0000000..423782f --- /dev/null +++ b/src/main/kotlin/org/gitanimals/guild/infra/HttpClientErrorHandler.kt @@ -0,0 +1,28 @@ +package org.gitanimals.guild.infra + +import org.gitanimals.core.AuthorizationException +import org.springframework.http.HttpStatus +import org.springframework.http.client.ClientHttpResponse +import org.springframework.web.client.ResponseErrorHandler + + +class HttpClientErrorHandler : ResponseErrorHandler { + + override fun hasError(response: ClientHttpResponse): Boolean { + return response.statusCode.isError + } + + override fun handleError(response: ClientHttpResponse) { + val body = response.body.bufferedReader().use { it.readText() } + when { + response.statusCode.isSameCodeAs(HttpStatus.UNAUTHORIZED) -> + throw AuthorizationException(body) + + response.statusCode.is4xxClientError -> + throw IllegalArgumentException(body) + + response.statusCode.is5xxServerError -> + throw IllegalStateException(body) + } + } +} diff --git a/src/main/kotlin/org/gitanimals/render/controller/BackgroundController.kt b/src/main/kotlin/org/gitanimals/render/controller/BackgroundController.kt index d3157e2..72260d9 100644 --- a/src/main/kotlin/org/gitanimals/render/controller/BackgroundController.kt +++ b/src/main/kotlin/org/gitanimals/render/controller/BackgroundController.kt @@ -45,6 +45,11 @@ class BackgroundController( @RequestParam(name = "name") name: String, ) = userFacade.deleteField(token, FieldType.valueOf(name.uppercase())) + @ExceptionHandler(IllegalStateException::class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + fun handleIllegalArgumentException(exception: IllegalStateException): org.gitanimals.guild.controller.response.ErrorResponse = + org.gitanimals.guild.controller.response.ErrorResponse.from(exception) + @ExceptionHandler(IllegalArgumentException::class) @ResponseStatus(HttpStatus.BAD_REQUEST) fun handleIllegalArgumentException(illegalArgumentException: IllegalArgumentException): ErrorResponse = diff --git a/src/main/kotlin/org/gitanimals/render/controller/InternalPersonaController.kt b/src/main/kotlin/org/gitanimals/render/controller/InternalPersonaController.kt index 0a63c83..db55cc3 100644 --- a/src/main/kotlin/org/gitanimals/render/controller/InternalPersonaController.kt +++ b/src/main/kotlin/org/gitanimals/render/controller/InternalPersonaController.kt @@ -1,7 +1,7 @@ package org.gitanimals.render.controller import org.gitanimals.core.IdGenerator -import org.gitanimals.render.app.AuthorizationException +import org.gitanimals.core.AuthorizationException import org.gitanimals.render.app.UserFacade import org.gitanimals.render.controller.request.AddMultiplyPersonaRequest import org.gitanimals.render.controller.request.AddPersonaRequest diff --git a/src/main/kotlin/org/gitanimals/render/controller/PersonaController.kt b/src/main/kotlin/org/gitanimals/render/controller/PersonaController.kt index 5429161..ca29129 100644 --- a/src/main/kotlin/org/gitanimals/render/controller/PersonaController.kt +++ b/src/main/kotlin/org/gitanimals/render/controller/PersonaController.kt @@ -1,7 +1,7 @@ package org.gitanimals.render.controller import org.gitanimals.core.PersonaType -import org.gitanimals.render.app.AuthorizationException +import org.gitanimals.core.AuthorizationException import org.gitanimals.render.app.UserFacade import org.gitanimals.render.app.request.MergePersonaRequest import org.gitanimals.render.controller.response.ErrorResponse @@ -82,6 +82,11 @@ class PersonaController( fun handleIllegalArgumentException(exception: IllegalArgumentException): ErrorResponse = ErrorResponse.from(exception) + @ExceptionHandler(IllegalStateException::class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + fun handleIllegalArgumentException(exception: IllegalStateException): org.gitanimals.guild.controller.response.ErrorResponse = + org.gitanimals.guild.controller.response.ErrorResponse.from(exception) + @ExceptionHandler(AuthorizationException::class) @ResponseStatus(HttpStatus.UNAUTHORIZED) fun handleAuthorizationException(exception: AuthorizationException): ErrorResponse = diff --git a/src/main/kotlin/org/gitanimals/render/infra/RestIdentityApi.kt b/src/main/kotlin/org/gitanimals/render/infra/RestIdentityApi.kt index 6ee94a9..f1f52c1 100644 --- a/src/main/kotlin/org/gitanimals/render/infra/RestIdentityApi.kt +++ b/src/main/kotlin/org/gitanimals/render/infra/RestIdentityApi.kt @@ -1,6 +1,6 @@ package org.gitanimals.render.infra -import org.gitanimals.render.app.AUTHORIZATION_EXCEPTION +import org.gitanimals.core.AUTHORIZATION_EXCEPTION import org.gitanimals.render.app.IdentityApi import org.springframework.http.HttpHeaders import org.springframework.stereotype.Component