法拉第版本:
法拉第 (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 ,对于缺乏文档表示歉意,这是我们试图在 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> ||= {}
无论如何,很高兴知道您的问题现在已经解决了👍!
最有用的评论
感谢@yusefu的反馈,并对 TypeError 感到抱歉。
我认为问题在于
@connections
应该是一个哈希,而不是一个数组,我的错!无论如何,很高兴知道您的问题现在已经解决了👍!