Jerith online - January 24th, 2008 [entries|archive|friends|userinfo]
jerith

[ website | jerith.za.net ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

January 24th, 2008

Ruby rant: Timeout::Error [Jan. 24th, 2008|05:44 pm]
[Tags|, , ]

I am currently filled with hate and loathing. I'm going to need a few moments to cool off before I carry on working.

I was trying to make an http call from an irb session full of state I had carefully collected. Most of the code I used is in a script, but I had been doing a substantial amount of exploration over data from a few different place. While waiting for a large dataset from a busy server on the other end of a high-latency link, I got a timeout in the HTTP receive stuff. This in itself would not be a problem, except it crashed my irb session.

The problem is with the exception that a timeout raises:
module Timeout
  class Error < Interrupt
  end
end

The initiated will know that (a subset of) the Ruby exception hierarchy looks something like this:
Exception
  - StandardError
    - RuntimeError
    - ZeroDivisionError
  - ScriptError
    - SyntaxError
  - SystemExit
  - SignalException
    - Interrupt

The important bit there is that all the stuff you can reasonably expect to recover from is under StandardError. Because of this, a default rescue block will not catch anything that isn't a StandardError. The observant reader will notice that I helpfully showed Interrupt's position in the hierarchy. The observant reader will also notice that it is not a subclass of StandardError. This means that you need to catch it explicitly, or it will cause a crash.

Now, my theory is that Timeout was written by someone who misinterpreted "Interrupt" as meaning "interrupt what I'm doing", not "interrupt my application". This would be understandable, although still not acceptable, in a third-party library. Timeout is a core standard library module, however.

To summarise: If you're using the standard Ruby timeout mechanism, which you are if you use the HTTP libraries and almost certainly a whole host of others, you need to explicitly catch Timeout::Error or have a dodgy network bring your entire application crashing down around you.
Link13 comments|Leave a comment

navigation
[ viewing | January 24th, 2008 ]
[ go | Previous Day|Next Day ]

Advertisement