6

Can anyone explain why I might see this stack (caused by an HTTParty::post request) when the call to the method looks like this:

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

The stack:

/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'

As you can see, I am handling the Timeout::Error exception. This is in Ruby 1.8.7. I am well aware that in Ruby 1.8.7, StandardException and TimeoutException have different inheritance trees, so I handle both, but it does not seem to make a difference.

esilver
  • 27,713
  • 23
  • 122
  • 168
  • I'm having a similar problem. What's worse is that I've actually set up a fake service locally and the error is rescued successfully when I cause a timeout on my local system. In production, the error handler never gets called. – Steve Jorgensen Jul 24 '13 at 00:07

1 Answers1

4

When you omit the exception class in rescue, it will capture any StandardError. Since Timeout::Error is a subclass of StandardError, it will be captured by the first rescue statement. If you want to separately capture it, you have to place that before the omitted one:

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
sawa
  • 165,429
  • 45
  • 277
  • 381
  • 5
    Timeout::Error is not a subclass of StandardError in Ruby 1.8.7: http://martinciu.com/2010/12/ruby-timeout-error-is-not-a-standard-error.html and http://jerith.livejournal.com/40063.html . Moreover, in the problem I am facing, the exception is not handle either by rescue Timeout::Error or by the naked rescue. – esilver Mar 20 '12 at 19:22