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

如何针对单个请求修改Faraday中间件配置?

针对特定Faraday请求实现自定义重试逻辑

问题描述

已配置好全局Faraday客户端,默认针对网络错误、5xx状态码进行3次重试:

client = Faraday.new(url: base_url) do |f|
  f.request :retry, { max: 3, backoff_factor: 2 }
  f.request :authorization, 'Bearer', -> { access_token }
  f.request :json
  f.response :json
  f.response :raise_error
end

现在需要针对特定请求/wait-for-data,在响应成功但env.body[:data][:ready] == false时触发重试,且调整最大重试次数为10次,希望能在发起请求时动态指定重试规则。

可行实现方案

方案1:全局重试中间件支持动态配置

修改全局的重试中间件,让它读取请求的自定义参数来覆盖默认重试逻辑和次数,无需创建新客户端即可实现特定请求的自定义重试:

首先更新客户端的重试配置:

client = Faraday.new(url: base_url) do |f|
  f.request :retry, { 
    # 默认最大重试次数
    max: 3,
    backoff_factor: 2,
    # 自定义重试判断逻辑:优先执行默认规则,再检查请求传入的自定义规则
    retry_if: ->(env, exc) {
      # 保留默认的重试触发条件(网络错误、5xx响应)
      default_retry = Faraday::Request::Retry.new.default_retry_if.call(env, exc)
      # 读取请求中传入的自定义重试条件
      custom_retry = env.request.options[:retry_options]&.fetch(:retry_if, ->(_,__) { false })&.call(env, exc)
      default_retry || custom_retry
    },
    # 动态计算最大重试次数:优先使用请求传入的配置,否则用默认值
    max: ->(env) {
      env.request.options[:retry_options]&.fetch(:max, 3)
    }
  }

  # 其他中间件保持不变
  f.request :authorization, 'Bearer', -> { access_token }
  f.request :json
  f.response :json
  f.response :raise_error
end

发起特定请求时,传入自定义的重试配置:

client.get("/wait-for-data") do |req|
  req.options[:retry_options] = {
    max: 10,
    retry_if: ->(env, _exc) {
      env.body.dig(:data, :ready) == false
    }
  }
end

方案2:创建临时客户端处理特定请求

如果不想修改全局配置,可以复制原客户端的配置,移除原有重试中间件后添加自定义的重试规则,用这个临时客户端发起请求:

# 复制原客户端的连接配置
custom_client = client.dup do |f|
  # 移除原有的重试中间件
  f.builder.delete(Faraday::Request::Retry)
  # 添加自定义的重试配置
  f.request :retry, {
    max: 10,
    backoff_factor: 2,
    retry_if: ->(env, _exc) {
      env.body.dig(:data, :ready) == false
    }
  }
end

# 使用临时客户端发起请求
custom_client.get("/wait-for-data")

注意事项

  • 因为配置了response :json中间件,响应体已经被解析为Hash,所以可以直接通过env.body访问数据;
  • raise_error中间件只会在响应状态码为4xx/5xx时抛出异常,成功响应不会触发异常,因此需要在retry_if中直接检查响应体内容来触发重试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 23:11:36