如何在伪装错误解码器中封送多个异常?

时间:2019-09-04 06:42:39

标签: java spring kotlin spring-cloud-feign feign

我正在为假冒客户实现假冒错误解码器。 如何找出哪个假客户端方法异常被抛出?

我有一个伪装客户PaymentClient,两个端点各自抛出不同的异常。在错误解码器中,我应该知道哪个端点引发了异常,因此我可以选择适当的异常类来编组响应。

这是我的客户,具有转账和付款方式。

@FeignClient(value = "payment-service", url = "\${payment-service.url}", configuration = [FeignPaymentServiceConfiguration::class])
interface PaymentClient {

    @DeleteMapping(value = ["/transfers/{id}"])
    fun deleteTransfer(@PathVariable("id") id: Long): Transfer

    @PostMapping(value = ["/payments"])
    fun createPayment(request: Payment): Payment
}

在我的错误解码器中,我想知道抛出了哪个异常(TransferExceptionPaymentException)。一个方法仅引发一个异常,因此,如果我知道触发异常的方法,那么我就知道异常类。

class PaymentServiceErrorDecoder(private val objectMapper: ObjectMapper) : ErrorDecoder {

    override fun decode(methodKey: String, response: Response): Exception? {
        return marshalException(methodKey, response)
    }

    private fun marshalException(methodKey: String, response: Response): Exception? {
        if (response?.body() == null) {
            return null
        }

        return try {
            marshalException(response.status(), convertBodyToString(response.body()), methodKey)
        } catch (e: IOException) { null }
    }

    @Throws(IOException::class)
    private fun marshalException(status: Int, content: String, methodKey: String): Exception {

// TODO: at this point I should somehow know which method thew exception to choose the right one 

        val exception = objectMapper.readValue(content, PaymentException::class.java)
        return exception
    }
}

这里有两个可以抛出的异常。

class TransferException(
    var transferErrors: List<TransferError> = mutableListOf(),
    message: String
) : RuntimeException(message) {

    class TransferError {
        val transferId: Long? = null
        val message: String? = null
    }
}
class PaymentException(
    var transferErrors: List<ApiError> = mutableListOf(),
    message: String
) : RuntimeException(message) {

    class PaymentError {
        val code: String? = null,
        val field: String? = null,
        val message: String? = null,
        val argument: String? = null,   
    }
}

解决方案之一是使用methodKey(例如PaymentClient#deleteTransfer(Long))来定义方法,但是我将紧密联系方法命名。 如果有的话,您是如何解决这个问题的?付款服务是否有不良的例外政策?

0 个答案:

没有答案