【问题标题】:Execution expired exception crashing Ruby thread, but Timeout::Error is handled执行过期异常导致 Ruby 线程崩溃,但 Timeout::Error 被处理
【发布时间】:2012-03-20 03:49:04
【问题描述】:

任何人都可以解释为什么当对方法的调用如下所示时我可能会看到这个堆栈(由 HTTParty::post 请求引起):

begin
  response = HTTParty::post(url, options)
rescue
  logger.warn("Could not post to #{url}")      
rescue Timeout::Error
  logger.warn("Could not post to #{url}: timeout")      
end

堆栈:

/usr/local/lib/ruby/1.8/timeout.rb:64:in `timeout'
/usr/local/lib/ruby/1.8/net/protocol.rb:134:in `rbuf_fill'
/usr/local/lib/ruby/1.8/net/protocol.rb:104:in `read_all'
/usr/local/lib/ruby/1.8/net/http.rb:2228:in `read_body_0'
/usr/local/lib/ruby/1.8/net/http.rb:2181:in `read_body'
/usr/local/lib/ruby/1.8/net/http.rb:2206:in `body'
/usr/local/lib/ruby/1.8/net/http.rb:2145:in `reading_body'
/usr/local/lib/ruby/1.8/net/http.rb:1053:in `request_without_newrelic_trace'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/instrumentation/net.rb:20:in `request'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/method_tracer.rb:242:in `trace_execution_scoped'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/instrumentation/net.rb:19:in `request'
/usr/local/lib/ruby/1.8/net/http.rb:1037:in `request_without_newrelic_trace'
/usr/local/lib/ruby/1.8/net/http.rb:543:in `start'
/usr/local/lib/ruby/1.8/net/http.rb:1035:in `request_without_newrelic_trace'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/instrumentation/net.rb:20:in `request'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/method_tracer.rb:242:in `trace_execution_scoped'
[GEM_ROOT]/gems/newrelic_rpm-3.1.1/lib/new_relic/agent/instrumentation/net.rb:19:in `request'
[GEM_ROOT]/gems/httparty-0.7.8/lib/httparty/request.rb:69:in `perform'
[GEM_ROOT]/gems/httparty-0.7.8/lib/httparty.rb:390:in `perform_request'
[GEM_ROOT]/gems/httparty-0.7.8/lib/httparty.rb:358:in `post'
[GEM_ROOT]/gems/httparty-0.7.8/lib/httparty.rb:426:in `post'

如您所见,我正在处理 Timeout::Error 异常。这是在 Ruby 1.8.7 中。我很清楚,在 Ruby 1.8.7 中,StandardException 和 TimeoutException 有不同的继承树,所以我处理了这两个,但似乎没有什么区别。

【问题讨论】:

  • 我遇到了类似的问题。更糟糕的是,我实际上已经在本地设置了一个虚假服务,并且当我在本地系统上导致超时时,错误被成功挽救。在生产环境中,永远不会调用错误处理程序。

标签: ruby exception-handling httparty timeoutexception


【解决方案1】:

当您省略rescue 中的异常类时,它将捕获任何StandardError。由于Timeout::ErrorStandardError 的子类,因此它将被第一个rescue 语句捕获。如果你想单独捕获它,你必须把它放在省略的前面:

begin
  response = HTTParty::post(url, options)
rescue Timeout::Error
  logger.warn("Could not post to #{url}: timeout")      
rescue
  logger.warn("Could not post to #{url}")      
end

【讨论】:

猜你喜欢
  • 2011-09-27
  • 1970-01-01
  • 2012-08-15
  • 1970-01-01
  • 2013-10-27
  • 1970-01-01
  • 2016-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多