我正在使用Rails 4.2.3和Nokogiri从网站获取数据。当我没有从服务器得到任何响应时,我想执行一个动作,所以我有:
begin
content = open(url).read
if content.lstrip[0] == '<'
doc = Nokogiri::HTML(content)
else
begin
json = JSON.parse(content)
rescue JSON::ParserError => e
content
end
end
rescue Net::OpenTimeout => e
attempts = attempts + 1
if attempts <= max_attempts
sleep(3)
retry
end
end
请注意,这与从服务器获取500不同。我只想在没有响应的情况下重试,因为我没有得到TCP连接,或者因为服务器没有响应(或者其他一些原因导致我没有得到任何响应)。除了我的方式之外,还有更通用的方法来考虑这种情况吗?我觉得我还没有想到很多其他异常类型。
答案 0 :(得分:4)
这是一个通用示例,您可以如何定义HTTP连接的超时持续时间,并在获取内容(编辑)时出现任何错误时执行多次重试
require 'open-uri'
require 'nokogiri'
url = "http://localhost:3000/r503"
openuri_params = {
# set timeout durations for HTTP connection
# default values for open_timeout and read_timeout is 60 seconds
:open_timeout => 1,
:read_timeout => 1,
}
attempt_count = 0
max_attempts = 3
begin
attempt_count += 1
puts "attempt ##{attempt_count}"
content = open(url, openuri_params).read
rescue OpenURI::HTTPError => e
# it's 404, etc. (do nothing)
rescue SocketError, Net::ReadTimeout => e
# server can't be reached or doesn't send any respones
puts "error: #{e}"
sleep 3
retry if attempt_count < max_attempts
else
# connection was successful,
# content is fetched,
# so here we can parse content with Nokogiri,
# or call a helper method, etc.
doc = Nokogiri::HTML(content)
p doc
end
答案 1 :(得分:4)
在拯救例外方面,您应该明确了解:
在您的代码中,获取内容的行也是可以看到网络错误的行:
content = open(url).read
如果您转到documentation for the OpenURI module,您会看到它使用Net::HTTP
&amp;朋友们获取任意URI的内容。
确定Net::HTTP
可以提出的内容实际上非常复杂,但幸运的是,其他人已经为您完成了这项工作。 Thoughtbot的吊杆项目有lists of common network errors你可以使用。请注意,其中一些错误与您考虑的网络条件不同,例如重置连接。我认为值得拯救这些产品,但请随意根据您的具体需求进行调整。
所以这里的代码应该是什么样的(跳过Nokogiri和JSON部分来简化一些事情): 要求&#39; net / http&#39; 要求&#39; open-uri&#39;
HTTP_ERRORS = [
EOFError,
Errno::ECONNRESET,
Errno::EINVAL,
Net::HTTPBadResponse,
Net::HTTPHeaderSyntaxError,
Net::ProtocolError,
Timeout::Error,
]
MAX_RETRIES = 3
attempts = 0
begin
content = open(url).read
rescue *HTTP_ERRORS => e
if attempts < MAX_RETRIES
attempts += 1
sleep(2)
retry
else
raise e
end
end
答案 2 :(得分:1)
我会考虑使用Timeout在短时间内引发异常:
tappedViewOverlay