Skip to content

Commit

Permalink
[KAN-8] global exception 처리 작업 (#5)
Browse files Browse the repository at this point in the history
* [KAN-8] global exception 처리 작업

* [KAN-8] global exception 처리 작업 - lint
  • Loading branch information
sinkyoungdeok authored Mar 28, 2024
1 parent ca2bc2b commit c5f1c42
Show file tree
Hide file tree
Showing 5 changed files with 205 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.restaurant.be.common.exception

import org.springframework.http.HttpStatus
import org.springframework.web.server.ResponseStatusException

open class GlobalException : ResponseStatusException {
constructor(status: HttpStatus?) : super(status!!)
constructor(status: HttpStatus?, reason: String?) : super(status!!, reason)
constructor(status: HttpStatus?, reason: String?, cause: Throwable?) : super(
status!!,
reason,
cause
)

companion object {
private const val serialVersionUID = -1L
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.restaurant.be.common.exception

import com.fasterxml.jackson.databind.exc.MismatchedInputException
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
import com.restaurant.be.common.response.CommonResponse
import com.restaurant.be.common.response.Error
import com.restaurant.be.common.response.ErrorCode
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.validation.FieldError
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestControllerAdvice
import org.springframework.web.bind.support.WebExchangeBindException
import org.springframework.web.server.ServerWebExchange
import org.springframework.web.server.ServerWebInputException

@RestControllerAdvice
class GlobalExceptionHandler {

@ExceptionHandler(ServerException::class)
fun handleServerException(
ex: ServerException,
exchange: ServerWebExchange
): ResponseEntity<Any> {
val response = CommonResponse.fail(ex.message, ex.javaClass.simpleName)
return ResponseEntity(response, null, ex.code)
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = [ServerWebInputException::class])
fun methodArgumentNotValidException(
e: ServerWebInputException,
exchange: ServerWebExchange
): CommonResponse<String?> {
val data =
if (e.cause?.cause is MissingKotlinParameterException) {
val param = (e.cause?.cause as MissingKotlinParameterException).parameter.name
"항목 ${param}을 확인해주세요"
} else if (e.cause?.cause is MismatchedInputException) {
e.message
} else {
null
}

val errorResponse = CommonResponse.fail(data, ErrorCode.COMMON_NULL_PARAMETER)
return errorResponse
}

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(value = [WebExchangeBindException::class])
fun methodArgumentNotValidException(
e: WebExchangeBindException,
exchange: ServerWebExchange
): CommonResponse<String> {
val errors = mutableListOf<Error>()
e.allErrors.forEach {
val error =
Error(
field = (it as FieldError).field,
message = it.defaultMessage,
value = it.rejectedValue
)
errors.add(error)
}

val errorResponse =
CommonResponse
.fail(errors.toString(), ErrorCode.COMMON_INVALID_PARAMETER)

return errorResponse
}

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(value = [Exception::class])
fun exception(
e: Exception,
exchange: ServerWebExchange
): CommonResponse<String?> {
val errorResponse = CommonResponse.fail(e.message, e::class.java.simpleName)
return errorResponse
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.restaurant.be.common.exception

sealed class ServerException(
val code: Int,
override val message: String
) : RuntimeException(message)
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.restaurant.be.common.response

data class CommonResponse<T>(
val result: Result,
val data: T?,
val message: String,
val errorCode: String?
) {

companion object {
// status 200 + success (message가 있을 경우)
fun <T> success(data: T, message: String): CommonResponse<T> {
return CommonResponse(
result = Result.SUCCESS,
data = data,
message = message,
errorCode = null
)
}

// status 200 + success (message가 없을 경우)
fun <T> success(data: T): CommonResponse<T> {
return CommonResponse(
result = Result.SUCCESS,
data = data,
message = "",
errorCode = null
)
}

// status 200 + success (data가 없을 경우)
fun <T> success(): CommonResponse<T> {
return CommonResponse(
result = Result.SUCCESS,
data = null,
message = "",
errorCode = null
)
}

// status 200 + fail
fun <T> fail(data: T, message: String): CommonResponse<T> {
return CommonResponse(
result = Result.FAIL,
data = data,
message = message,
errorCode = null
)
}

fun <T> fail(data: T, errorCode: ErrorCode): CommonResponse<T> {
return CommonResponse(
result = Result.FAIL,
data = data,
message = errorCode.errorMsg,
errorCode = errorCode.name
)
}

fun fail(message: String, exceptionName: String): CommonResponse<Nothing> {
return CommonResponse(
result = Result.FAIL,
data = null,
message = message,
errorCode = exceptionName
)
}
}

enum class Result {
SUCCESS,
FAIL
}
}

data class Error(
val field: String? = null,
val message: String? = null,
val value: Any? = null
)
18 changes: 18 additions & 0 deletions src/main/kotlin/com/restaurant/be/common/response/ErrorCode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.restaurant.be.common.response

enum class ErrorCode(
val errorMsg: String
) {
// 500
COMMON_SYSTEM_ERROR("일시적인 오류가 발생했습니다. 잠시 후 다시 시도해주세요."),

// 400
COMMON_NULL_PARAMETER("빠뜨린 값이 없는지 확인 해주세요."),
COMMON_INVALID_PARAMETER("요청한 값이 올바르지 않습니다.")

;

fun getErrorMsg(vararg arg: Any?): String {
return String.format(errorMsg, *arg)
}
}

0 comments on commit c5f1c42

Please sign in to comment.