You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中使用Resilience4J重试逻辑遇类型不匹配错误的解决方法

解决Resilience4J重试逻辑的类型不匹配问题

核心问题分析

你的错误源于两个关键点:

  1. 类型适配问题:Resilience4J的Decorators.ofSupplier期望的是Java的Supplier接口,虽然Scala的Function0可以隐式转换,但返回值的泛型需要明确统一。
  2. 重试触发逻辑不匹配:默认重试仅在抛出异常时触发,而你代码中部分错误场景是返回Some[(String,String)](正常返回值),不会触发重试,同时导致类型推断异常。

解决方案一:将业务错误转为异常触发重试(推荐)

通过抛出自定义异常,让Resilience4J的默认重试逻辑捕获并触发重试,同时统一返回值类型:

  1. 先定义自定义异常类:
case class VertexTaxException(code: String, message: String) extends Exception(s"Tax Error [$code]: $message")
  1. 修改原有代码,将返回Some的场景改为抛出异常:
val reversalRequestResult = Decorators.ofSupplier(() => {
  determinationService.getTax(getTaxRequest, runID) match {
    case Success(getTaxResponse) =>
      if (vertexComplianceExceptionHandler.containsGrpcResponseExceptions(getTaxResponse)) {
        val (errorCode, errorMsg) = vertexComplianceExceptionHandler.handleGrpcResponseExceptions(getTaxResponse)
        LOGGER.error("Response has a failure/unsuccessful status for a invoice request")
        throw VertexTaxException(errorCode, errorMsg)
      } else {
        eventInfoCase.record_status = VertexComplianceConstant.RECORD_STATUS_SUCCESS
        getTaxResponse // 成功时返回具体响应对象
      }
    case Failure(exception) =>
      val (errorCode, errorMsg) = vertexComplianceExceptionHandler.handleHardGrpcExceptions(exception)
      throw VertexTaxException(errorCode, errorMsg)
  }
}).withRetry(vertexGetTaxResilience.getDefaultRetryInstance())
.get()
  1. 确保重试配置(getDefaultRetryInstance())包含对VertexTaxException的重试规则,若默认配置是重试所有异常则无需额外修改。

解决方案二:自定义重试规则,支持返回值判断

若希望保留Option返回值结构,可通过自定义RetryConfig指定当返回Some时触发重试:

import io.github.resilience4j.retry.Retry
import io.github.resilience4j.retry.RetryConfig
import java.time.Duration

// 构建自定义重试配置
val retryConfig = RetryConfig.custom()
  .maxAttempts(3) // 最大重试次数
  .waitDuration(Duration.ofSeconds(1)) // 重试间隔
  .retryOnResult[Option[(String, String)]] { result =>
    result.isDefined // 返回Some时触发重试
  }
  .retryOnException(_ => true) // 异常场景也触发重试
  .build()

val retry = Retry.of("vertex-get-tax-retry", retryConfig)

// 用Retry.decorateSupplier包装逻辑
val reversalRequestResult = Retry.decorateSupplier(retry, () => {
  determinationService.getTax(getTaxRequest, runID) match {
    case Success(getTaxResponse) =>
      if (vertexComplianceExceptionHandler.containsGrpcResponseExceptions(getTaxResponse)) {
        LOGGER.error("Response has a failure/unsuccessful status for a invoice request")
        Some(vertexComplianceExceptionHandler.handleGrpcResponseExceptions(getTaxResponse))
      } else {
        eventInfoCase.record_status = VertexComplianceConstant.RECORD_STATUS_SUCCESS
        None
      }
    case Failure(exception) =>
      Some(vertexComplianceExceptionHandler.handleHardGrpcExceptions(exception))
  }
}).get()

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:24:42