ruby - Faraday::ConnectionFailed 的意外行为
问题描述
我正在为一个 API 编写一个客户端,该 API 从Faraday::ConnectionFailed
和Faraday::TimeoutError
重试相同的方法MAX_RETRIES
时间。
这是涉及的主要方法:
def benchmark_request(path)
retries ||= 0
request_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
response = yield
total_request_seconds = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start_time)
Rails.logger.info "client request took (#{total_request_seconds}s): #{ENV['API_PATH_PREFIX']}#{path}"
response
rescue Faraday::ConnectionFailed, Faraday::TimeoutError => e
retries += 1
retry if retries <= MAX_RETRIES
end
调用的方法是:
def get(path, params = {})
benchmark_request(path) { token.get("#{ENV['API_PATH_PREFIX']}#{path}", params) }
end
token.get
来自oauth2
正在使用的宝石Faraday
这是有趣的一点。我写了 2 个规范,每个我想处理的异常都有 1 个。
context 'when the endpoint raises a ConnectionFailed' do
let(:token_expires_at) { 1.hour.from_now.to_i }
let(:response_body) { '' }
let(:response_status) { 200 }
before do
allow(token).to receive(:get).and_raise(Faraday::ConnectionFailed)
described_class.get(api_endpoint)
end
it 'is called MAX_RETRIES times' do
expect(token).to have_received(:get).exactly(3).times
end
end
context 'when the endpoint raises a TimeoutError' do
let(:token_expires_at) { 1.hour.from_now.to_i }
let(:response_body) { '' }
let(:response_status) { 200 }
before do
allow(token).to receive(:get).and_raise(Faraday::TimeoutError)
described_class.get(api_endpoint)
end
it 'is called MAX_RETRIES times' do
expect(token).to have_received(:get).exactly(3).times
end
end
测试测试ConnectionFailed
失败,测试测试TimeoutError
为绿色。引发的异常是:
1) Client::Base.get when the endpoint raises a ConnectionFailed is called MAX_RETRIES times
Failure/Error: token.get(path, params)
ArgumentError:
wrong number of arguments (given 0, expected 1..2)
# /home/ngw/.rvm/gems/ruby-2.6.2/gems/faraday-0.15.4/lib/faraday/error.rb:7:in `initialize'
# ./app/lib/client/base.rb:13:in `get'
# ./spec/lib/client/base_spec.rb:111:in `block (4 levels) in <top (required)>'
这显然是关于如何初始化异常。
有人知道吗?
解决方案
这是因为 Farady::ConnectionFailed 继承自 Faraday::Error 类,该类def initialize
至少需要一个参数。在此处 (Error)和此处 (ConnectionFailed)检查源。
TimeoutError 有效,因为它的默认值设置exc
为"timeout"
here。
乍一看很难发现,我完全理解你也迷路了。
正如@MikeRogers0 在他的解决方案中提到的那样,您必须在and_raise
.
我希望你会发现这个答案有帮助。
推荐阅读
- javascript - 滚动文档,使单击的元素出现在页面顶部
- java - 如何让nestedscrollview 可以滚动或不滚动?
- gesture - 如何平移然后立即用锤子js捏?
- angularjs - ngTableEventsChannel.onAfterDataFiltered 不起作用?
- sql - 如何添加列,然后使用过程更新 sql server 中的列
- css - React CSS Webpack Hashing & Usage with semantic-ui-sass, semantic-ui-react
- c# - 通过更改查询号更新整个列表
- continuous-integration - 有什么方法可以将 dotenv 与 Bitbucket Pipelines 一起使用?
- module - Julia:将模块拆分为多个文件
- php - html - 如何将选定的选项保存到数据库中