Faraday: 如何使用 POST 方法重试

创建于 2018-03-12  ·  3评论  ·  资料来源: lostisland/faraday

基础信息

  • 法拉第版本:
    法拉第 (0.11.0)
    faraday_middleware (0.11.0.1)
    faraday_middleware-aws-signers-v4 (0.1.5)

  • 红宝石版本:
    ruby 2.3.0p0(2015-12-25 修订版 53290)[x86_64-darwin15]

问题描述

我有一个访问某些 api 的接口,正在使用带有get方法的Faraday连接并设置重试,并且一切正常,直到我将方法更改为发布然后重试停止工作我用谷歌搜索了一下,所以我明白帖子不是包含在

IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]

参考: https ://github.com/lostisland/faraday/pull/437/files
如果我想重试 POST 但没有找到文档 dor retry_if ,我必须使用 retry_if

所以我的连接看起来像这样:

    def my_connection(my_api_endpoint)
      Faraday.new(url: my_api_endpoint) do |faraday|
        faraday.request  :retry, max: 5, exceptions:
          [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed]
         faraday.response :logger
         faraday.adapter  Faraday.default_adapter
         faraday.options[:open_timeout] = 10
      end
    end

并这样称呼它:

  res = my_connection(my_api_endpoint).post do |req|
    req.headers['Content-Type'] = 'application/json'
    req.options.timeout = 25
    req.body = body.to_json
  end

任何帮助都将受到欢迎。

最有用的评论

感谢@yusefu的反馈,并对 TypeError 感到抱歉。
我认为问题在于@connections应该是一个哈希,而不是一个数组,我的错!

<strong i="9">@connections</strong> ||= {}

无论如何,很高兴知道您的问题现在已经解决了👍!

所有3条评论

@yusefu ,对于缺乏文档表示歉意,这是我们试图在 v1.0 中解决的问题。
在此期间,让我帮助您解决问题。 基本上retry_if是一个选项,您可以准确地通过max: 5, exceptions: [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed] 。 唯一的区别是retry_if必须是一个函数(lambda 或 proc.
如果您不熟悉这些,我建议您使用proc ,可以使用Proc.new { ... }或多行Proc.new do ... end进行实例化。

所以如果你想使用retry_if你的例子会变成这样:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="17">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="18">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      retry_if: Proc.new do |env, exception|
        # your implementation goes here...
      end
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

但是,如果您的唯一目标是将 :post 添加到重试方法列表中,您还可以使用在您链接的 PR 上添加的methods选项:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="23">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="24">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      methods: Faraday::Request::Retry::IDEMPOTENT_METHODS + [:post]
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

请让我知道这是否有帮助😄

连接实例给出了 TypeError。

expected MyAPI::BadRequest, got #<TypeError: {:req=>{}, :res=>nil, :headers=>nil, :reason_phrase=>nil}> with backtrace:

但是通过简单地将post添加到 IDEMPOTENT_METHODS 中,现在可以重试
非常感谢@iMacTia 🙏它确实有效。

感谢@yusefu的反馈,并对 TypeError 感到抱歉。
我认为问题在于@connections应该是一个哈希,而不是一个数组,我的错!

<strong i="9">@connections</strong> ||= {}

无论如何,很高兴知道您的问题现在已经解决了👍!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

ioquatix picture ioquatix  ·  4评论

iMacTia picture iMacTia  ·  3评论

aleksb86 picture aleksb86  ·  3评论

mattmill30 picture mattmill30  ·  4评论

asf-stripe picture asf-stripe  ·  3评论