From 78de04713f3bf490036a8eaf1096ce9cdd447430 Mon Sep 17 00:00:00 2001 From: FatttSnake Date: Thu, 5 Oct 2023 21:10:05 +0800 Subject: [PATCH] Add exception handler --- .../top/fatweb/api/config/FilterConfig.kt | 18 ++++++++++ .../api/controller/ExceptionController.kt | 14 ++++++++ .../fatweb/api/entity/common/BusinessCode.kt | 6 ++++ .../fatweb/api/entity/common/ResponseCode.kt | 22 ++++++++++++ .../api/entity/common/ResponseResult.kt | 29 +++++++++++++++ .../top/fatweb/api/filter/ExceptionFilter.kt | 14 ++++++-- .../fatweb/api/handler/ExceptionHandler.kt | 35 +++++++++++++++++++ 7 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/top/fatweb/api/config/FilterConfig.kt create mode 100644 src/main/kotlin/top/fatweb/api/controller/ExceptionController.kt create mode 100644 src/main/kotlin/top/fatweb/api/entity/common/BusinessCode.kt create mode 100644 src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt create mode 100644 src/main/kotlin/top/fatweb/api/entity/common/ResponseResult.kt create mode 100644 src/main/kotlin/top/fatweb/api/handler/ExceptionHandler.kt diff --git a/src/main/kotlin/top/fatweb/api/config/FilterConfig.kt b/src/main/kotlin/top/fatweb/api/config/FilterConfig.kt new file mode 100644 index 0000000..71374f9 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/config/FilterConfig.kt @@ -0,0 +1,18 @@ +package top.fatweb.api.config + +import org.springframework.boot.web.servlet.FilterRegistrationBean +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import top.fatweb.api.filter.ExceptionFilter + +@Configuration +class FilterConfig { + @Bean + fun exceptionFilterRegistrationBean(exceptionFilter: ExceptionFilter): FilterRegistrationBean { + val registrationBean = FilterRegistrationBean(exceptionFilter) + registrationBean.setBeanName("exceptionFilter") + registrationBean.order = -100 + + return registrationBean + } +} \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/controller/ExceptionController.kt b/src/main/kotlin/top/fatweb/api/controller/ExceptionController.kt new file mode 100644 index 0000000..dcb7833 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/controller/ExceptionController.kt @@ -0,0 +1,14 @@ +package top.fatweb.api.controller + +import jakarta.servlet.http.HttpServletRequest +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@RestController +@RequestMapping("/error") +class ExceptionController { + @RequestMapping("/thrown") + fun thrown(request: HttpServletRequest) { + throw request.getAttribute("filter.error") as RuntimeException + } +} \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/entity/common/BusinessCode.kt b/src/main/kotlin/top/fatweb/api/entity/common/BusinessCode.kt new file mode 100644 index 0000000..02178f5 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/entity/common/BusinessCode.kt @@ -0,0 +1,6 @@ +package top.fatweb.api.entity.common + +enum class BusinessCode(val code: Int) { + SYSTEM(100), + DATABASE(200) +} \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt new file mode 100644 index 0000000..8749e68 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/entity/common/ResponseCode.kt @@ -0,0 +1,22 @@ +package top.fatweb.api.entity.common + +enum class ResponseCode(val code: Int) { + SYSTEM_OK(BusinessCode.SYSTEM, 0), + SYSTEM_LOGIN_SUCCESS(BusinessCode.SYSTEM, 20), + SYSTEM_PASSWORD_CHANGE_SUCCESS(BusinessCode.SYSTEM, 21), + SYSTEM_LOGOUT_SUCCESS(BusinessCode.SYSTEM, 22), + SYSTEM_TOKEN_RENEW_SUCCESS(BusinessCode.SYSTEM, 23), + SYSTEM_UNAUTHORIZED(BusinessCode.SYSTEM, 30), + SYSTEM_ACCESS_DENIED(BusinessCode.SYSTEM, 31), + SYSTEM_USER_DISABLE(BusinessCode.SYSTEM, 32), + SYSTEM_LOGIN_USERNAME_PASSWORD_ERROR(BusinessCode.SYSTEM, 33), + SYSTEM_OLD_PASSWORD_NOT_MATCH(BusinessCode.SYSTEM, 34), + SYSTEM_LOGOUT_FAILED(BusinessCode.SYSTEM, 35), + SYSTEM_TOKEN_ILLEGAL(BusinessCode.SYSTEM, 36), + SYSTEM_TOKEN_HAS_EXPIRED(BusinessCode.SYSTEM, 37), + SYSTEM_REQUEST_ILLEGAL(BusinessCode.SYSTEM, 40), + SYSTEM_ERROR(BusinessCode.SYSTEM, 50), + SYSTEM_TIMEOUT(BusinessCode.SYSTEM, 51); + + constructor(businessCode: BusinessCode, code: Int) : this(businessCode.code * 100 + code) +} \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/entity/common/ResponseResult.kt b/src/main/kotlin/top/fatweb/api/entity/common/ResponseResult.kt new file mode 100644 index 0000000..9559c1d --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/entity/common/ResponseResult.kt @@ -0,0 +1,29 @@ +package top.fatweb.api.entity.common + +import io.swagger.v3.oas.annotations.media.Schema +import java.io.Serializable + +class ResponseResult private constructor( + @Schema(description = "响应码", defaultValue = "200") + val code: Int, + + @Schema(description = "是否调用成功") + val success: Boolean, + + @Schema(description = "信息") + val msg: String, + + @Schema(description = "数据") + val data: T? +) : Serializable { + companion object { + fun build(code: ResponseCode, success: Boolean, msg: String, data: T?) = + ResponseResult(code.code, success, msg, data) + + fun success(code: ResponseCode = ResponseCode.SYSTEM_OK, msg: String = "success", data: T? = null) = + build(code, true, msg, data) + + fun fail(code: ResponseCode = ResponseCode.SYSTEM_ERROR, msg: String = "fail", data: T? = null) = + build(code, false, msg, data) + } +} \ No newline at end of file diff --git a/src/main/kotlin/top/fatweb/api/filter/ExceptionFilter.kt b/src/main/kotlin/top/fatweb/api/filter/ExceptionFilter.kt index 4fcfbc2..3097036 100644 --- a/src/main/kotlin/top/fatweb/api/filter/ExceptionFilter.kt +++ b/src/main/kotlin/top/fatweb/api/filter/ExceptionFilter.kt @@ -1,10 +1,18 @@ package top.fatweb.api.filter -import jakarta.servlet.* -import java.lang.Exception +import jakarta.servlet.Filter +import jakarta.servlet.FilterChain +import jakarta.servlet.ServletRequest +import jakarta.servlet.ServletResponse +import org.springframework.stereotype.Component +@Component class ExceptionFilter : Filter { - override fun doFilter(servletRequest: ServletRequest?, servletResponse: ServletResponse?, filterChain: FilterChain?) { + override fun doFilter( + servletRequest: ServletRequest?, + servletResponse: ServletResponse?, + filterChain: FilterChain? + ) { try { filterChain!!.doFilter(servletRequest, servletResponse) } catch (e: Exception) { diff --git a/src/main/kotlin/top/fatweb/api/handler/ExceptionHandler.kt b/src/main/kotlin/top/fatweb/api/handler/ExceptionHandler.kt new file mode 100644 index 0000000..4d982d0 --- /dev/null +++ b/src/main/kotlin/top/fatweb/api/handler/ExceptionHandler.kt @@ -0,0 +1,35 @@ +package top.fatweb.api.handler + +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.http.converter.HttpMessageNotReadableException +import org.springframework.security.authentication.InsufficientAuthenticationException +import org.springframework.web.bind.annotation.ExceptionHandler +import org.springframework.web.bind.annotation.RestControllerAdvice +import top.fatweb.api.entity.common.ResponseCode +import top.fatweb.api.entity.common.ResponseResult + +@RestControllerAdvice +class ExceptionHandler { + private val log: Logger = LoggerFactory.getLogger(this::class.java) + + @ExceptionHandler(value = [Exception::class]) + fun exceptionHandler(e: Exception): ResponseResult<*> { + return when (e) { + is InsufficientAuthenticationException -> { + log.debug(e.localizedMessage, e) + ResponseResult.fail(ResponseCode.SYSTEM_UNAUTHORIZED, e.localizedMessage, null) + } + + is HttpMessageNotReadableException -> { + log.debug(e.localizedMessage, e) + ResponseResult.fail(ResponseCode.SYSTEM_REQUEST_ILLEGAL, e.localizedMessage.split(":")[0], null) + } + + else -> { + log.error(e.localizedMessage, e) + ResponseResult.fail(ResponseCode.SYSTEM_ERROR, data = null) + } + } + } +} \ No newline at end of file