jerith ([info]jerith) wrote,
@ 2008-01-24 17:44:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
Entry tags:programming, rant, ruby

Ruby rant: Timeout::Error
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.



(Read 13 comments) - (Post a new comment)

Re: If you're ok with hacking the core libraries
(Anonymous)
2008-12-18 10:03 am UTC (link)
Of course that could have unintended consequences if other libs rely on catching Timeout::Error.

Fucking hell.

(Reply to this) (Parent)(Thread)

Re: If you're ok with hacking the core libraries
[info]jerith
2008-12-18 10:05 am UTC (link)
Quite.

(Reply to this) (Parent)(Thread)

Re: If you're ok with hacking the core libraries
(Anonymous)
2009-05-12 08:43 pm UTC (link)
What's wrong with putting this at the top of your code?

module Timeout
class Error < StandardError
end
end

(Reply to this) (Parent)(Thread)

Re: If you're ok with hacking the core libraries
[info]jerith
2009-05-13 10:04 am UTC (link)
I'm pretty sure I tried this, but it seems to work now.

Of course, it still suffers from the issue of breaking code that expects the usual hierarchy.

(Reply to this) (Parent)


(Read 13 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…