Wednesday, June 27, 2007

Nested Exceptions for Ruby

I missed nested exceptions in Ruby.

Some people have an aversion to nested exceptions (aka chained exceptions), but I think that's because they've only encountered them in a land of checked exceptions, where catching, wrapping, and rethrowing is often a defensive measure against an uncool method signature. (The two flavors of uncool are "throws RemoteException, SQLException, JimmysException, SomeOtherException, KitchenSink" and "throws Exception".)

In a world like ours where the only motivations to rescue and re-raise are

  • to add valuable contextual information or
  • to expose a clear interface to callers,

I think an exception holding a reference to its cause, including its cause's backtrace, could be nice.

Anyway, I missed nested exceptions in Ruby, so here's Nestegg, a gem enabling nesting of exceptions. It's brand new. It's tested, but not yet used in anger.

For now, it's just one module. If you include it in an exception class,

class ConfigurationError < StandardError
  include Nestegg::NestingException
end

then raise that exception from within a rescue block,

def load_config
  begin
    lines = read_config_file
    # ... then use it to do stuff 
    # ... stuff that might fail for other reasons
  rescue
    raise ConfigurationError
  end
end

it will automatically grab $! as its cause and make the cause's backtrace part of its own. You can also pass a cause into the constructor of your exception.

Take a look and tell me what you think.

2 comments:

Dan Manges said...

Cool gem John

Anonymous said...

Thanks. This saved me today.