generated from pricelees/issue-pr-template
refactor: PaymentClient 및 테스트에 새로 추가된 커스텀 예외 반영
This commit is contained in:
parent
498340f173
commit
e9fcc31dea
@ -4,17 +4,15 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import io.github.oshai.kotlinlogging.KLogger
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.springframework.http.HttpRequest
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.HttpStatusCode
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.http.client.ClientHttpResponse
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.client.RestClient
|
||||
import roomescape.common.exception.ErrorType
|
||||
import roomescape.common.exception.RoomescapeException
|
||||
import roomescape.payment.exception.PaymentErrorCode
|
||||
import roomescape.payment.exception.PaymentException
|
||||
import roomescape.payment.web.PaymentCancelRequest
|
||||
import roomescape.payment.web.PaymentCancelResponse
|
||||
import java.io.IOException
|
||||
import java.util.Map
|
||||
|
||||
@Component
|
||||
@ -43,7 +41,7 @@ class TossPaymentClient(
|
||||
{ req: HttpRequest, res: ClientHttpResponse -> handlePaymentError(res) }
|
||||
)
|
||||
.body(PaymentApproveResponse::class.java)
|
||||
?: throw RoomescapeException(ErrorType.PAYMENT_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
?: throw PaymentException(PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
|
||||
}
|
||||
|
||||
fun cancel(cancelRequest: PaymentCancelRequest): PaymentCancelResponse {
|
||||
@ -60,7 +58,7 @@ class TossPaymentClient(
|
||||
{ req: HttpRequest, res: ClientHttpResponse -> handlePaymentError(res) }
|
||||
)
|
||||
.body(PaymentCancelResponse::class.java)
|
||||
?: throw RoomescapeException(ErrorType.PAYMENT_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
?: throw PaymentException(PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
|
||||
}
|
||||
|
||||
private fun logPaymentInfo(paymentRequest: PaymentApproveRequest) {
|
||||
@ -80,32 +78,25 @@ class TossPaymentClient(
|
||||
private fun handlePaymentError(
|
||||
res: ClientHttpResponse
|
||||
): Nothing {
|
||||
val statusCode = res.statusCode
|
||||
val errorType = getErrorTypeByStatusCode(statusCode)
|
||||
val errorResponse = getErrorResponse(res)
|
||||
|
||||
throw RoomescapeException(
|
||||
errorType,
|
||||
"[ErrorCode = ${errorResponse.code}, ErrorMessage = ${errorResponse.message}]",
|
||||
statusCode
|
||||
)
|
||||
getErrorCodeByHttpStatus(res.statusCode).also {
|
||||
logTossPaymentError(res)
|
||||
throw PaymentException(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getErrorResponse(
|
||||
res: ClientHttpResponse
|
||||
): TossPaymentErrorResponse {
|
||||
private fun logTossPaymentError(res: ClientHttpResponse): TossPaymentErrorResponse {
|
||||
val body = res.body
|
||||
val errorResponse = objectMapper.readValue(body, TossPaymentErrorResponse::class.java)
|
||||
body.close()
|
||||
|
||||
log.error { "결제 실패. response: $errorResponse" }
|
||||
return errorResponse
|
||||
}
|
||||
|
||||
private fun getErrorTypeByStatusCode(
|
||||
statusCode: HttpStatusCode
|
||||
): ErrorType {
|
||||
private fun getErrorCodeByHttpStatus(statusCode: HttpStatusCode): PaymentErrorCode {
|
||||
if (statusCode.is4xxClientError) {
|
||||
return ErrorType.PAYMENT_ERROR
|
||||
return PaymentErrorCode.PAYMENT_CLIENT_ERROR
|
||||
}
|
||||
return ErrorType.PAYMENT_SERVER_ERROR
|
||||
return PaymentErrorCode.PAYMENT_PROVIDER_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ import org.springframework.test.web.client.ResponseActions
|
||||
import org.springframework.test.web.client.match.MockRestRequestMatchers.*
|
||||
import org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
|
||||
import org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess
|
||||
import roomescape.common.exception.ErrorType
|
||||
import roomescape.common.exception.RoomescapeException
|
||||
import roomescape.payment.exception.PaymentErrorCode
|
||||
import roomescape.payment.exception.PaymentException
|
||||
import roomescape.payment.web.PaymentCancelRequest
|
||||
import roomescape.payment.web.PaymentCancelResponse
|
||||
|
||||
@ -56,28 +56,32 @@ class TossPaymentClientTest(
|
||||
}
|
||||
}
|
||||
|
||||
test("400 에러 발생") {
|
||||
commonAction().andRespond {
|
||||
withStatus(HttpStatus.BAD_REQUEST)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(SampleTossPaymentConst.tossPaymentErrorJson)
|
||||
.createResponse(it)
|
||||
context("실패 응답") {
|
||||
fun runTest(httpStatus: HttpStatus, expectedError: PaymentErrorCode) {
|
||||
commonAction().andRespond {
|
||||
withStatus(httpStatus)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(SampleTossPaymentConst.tossPaymentErrorJson)
|
||||
.createResponse(it)
|
||||
}
|
||||
|
||||
// when
|
||||
val paymentRequest = SampleTossPaymentConst.paymentRequest
|
||||
|
||||
// then
|
||||
val exception = shouldThrow<PaymentException> {
|
||||
client.confirm(paymentRequest)
|
||||
}
|
||||
exception.errorCode shouldBe expectedError
|
||||
}
|
||||
|
||||
// when
|
||||
val paymentRequest = SampleTossPaymentConst.paymentRequest
|
||||
|
||||
// then
|
||||
val exception = shouldThrow<RoomescapeException> {
|
||||
client.confirm(paymentRequest)
|
||||
test("결제 서버에서 4XX 응답 시") {
|
||||
runTest(HttpStatus.BAD_REQUEST, PaymentErrorCode.PAYMENT_CLIENT_ERROR)
|
||||
}
|
||||
|
||||
assertSoftly(exception) {
|
||||
this.errorType shouldBe ErrorType.PAYMENT_ERROR
|
||||
this.invalidValue shouldBe "[ErrorCode = ERROR_CODE, ErrorMessage = Error message]"
|
||||
this.httpStatus shouldBe HttpStatus.BAD_REQUEST
|
||||
test("결제 서버에서 5XX 응답 시") {
|
||||
runTest(HttpStatus.INTERNAL_SERVER_ERROR, PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,26 +115,29 @@ class TossPaymentClientTest(
|
||||
}
|
||||
}
|
||||
|
||||
test("500 에러 발생") {
|
||||
commonAction().andRespond {
|
||||
withStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(SampleTossPaymentConst.tossPaymentErrorJson)
|
||||
.createResponse(it)
|
||||
context("실패 응답") {
|
||||
fun runTest(httpStatus: HttpStatus, expectedError: PaymentErrorCode) {
|
||||
commonAction().andRespond {
|
||||
withStatus(httpStatus)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(SampleTossPaymentConst.tossPaymentErrorJson)
|
||||
.createResponse(it)
|
||||
}
|
||||
|
||||
val cancelRequest: PaymentCancelRequest = SampleTossPaymentConst.cancelRequest
|
||||
|
||||
val exception = shouldThrow<PaymentException> {
|
||||
client.cancel(cancelRequest)
|
||||
}
|
||||
exception.errorCode shouldBe expectedError
|
||||
}
|
||||
|
||||
// when
|
||||
val cancelRequest: PaymentCancelRequest = SampleTossPaymentConst.cancelRequest
|
||||
|
||||
// then
|
||||
val exception = shouldThrow<RoomescapeException> {
|
||||
client.cancel(cancelRequest)
|
||||
test("결제 서버에서 4XX 응답 시") {
|
||||
runTest(HttpStatus.BAD_REQUEST, PaymentErrorCode.PAYMENT_CLIENT_ERROR)
|
||||
}
|
||||
|
||||
assertSoftly(exception) {
|
||||
this.errorType shouldBe ErrorType.PAYMENT_SERVER_ERROR
|
||||
this.invalidValue shouldBe "[ErrorCode = ERROR_CODE, ErrorMessage = Error message]"
|
||||
this.httpStatus shouldBe HttpStatus.INTERNAL_SERVER_ERROR
|
||||
test("결제 서버에서 5XX 응답 시") {
|
||||
runTest(HttpStatus.INTERNAL_SERVER_ERROR, PaymentErrorCode.PAYMENT_PROVIDER_ERROR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user