【发布时间】:2016-09-24 20:57:51
【问题描述】:
使用 Net::HTTP,我会定期发现下面的代码从 StandardError 中救出并显示“执行已过期”消息,尽管来自访问 URL 的 Web 服务器日志显示相应的响应已快速发送。当 Web 服务器日志显示响应时间超过 5 秒时,我通常会看到来自 Timeout::Error 的代码救援。
什么情况下会导致下面的代码以“执行已过期”而不是从 Timeout::Error 中挽救 StandardError?
这段代码在一个相对古老的 Ruby 1.9.3 上的多线程程序中运行,该平台不支持较新版本的 Ruby。虽然程序是多线程的,但显示的代码只能在单线程上运行。
begin
connection = Net::HTTP.new(uri.host, uri.port)
connection.open_timeout = 5
connection.read_timeout = 5
connection.start do |http|
request = Net::HTTP::Post.new("/reader_events")
request.body = body
response = http.request(request)
end
rescue StandardError => std_error
log "error sending event to server: #{std_error}"
rescue Timeout::Error => error
log "timeout sending event to server"
end
【问题讨论】:
-
尝试将您的
rescue Timeout::Error块放在另一个救援块之前。在 Ruby 中,大多数异常类都继承自 StandardError,所以如果 Timeout::Error 也是如此,我不会感到惊讶。如果是这种情况,那么错误将是一种 StandardError 和一种 Timeout::Error。第一个匹配的rescue处理程序获胜。 -
@HenrikN 很好。打印
Timeout::Error.ancestors表明它确实继承自StandardError。