Rescue clauses are amongst the few things in Ruby that care about the class
of your object, so when you do
begin
...
rescue Foo
...
end
the exception has got to be of kind Foo or a subclass. If rescueing exceptions followed
the message sending paradigm, it could have looked like this fictitious snippet:
begin
...
rescue foo
...
rescue standard_error
In practice, the fact that rescue cares about the class means that you typically define
your exceptions using
MyException = Class.new(StandardError)
Indeed, Ruby wants the class used in the rescue clause to be derived from
Exception. Since an unqualified rescue handles all StandardError and derived
exceptions (but not all Exceptions), you'll often end up subclassing that
exception class.
Ruby lacks multiple inheritance, so you cannot have an exception class that
derives from e.g. both BackendError and CriticalError, making the following
impossible, right?
def foo(*args)
...
rescue CriticalError
raise
rescue BackEndError
end
begin
foo(*stuff)
rescue BackEndError
end
Ruby does have multiple inheritance, it's just that it's been given
another name (and it's got a couple restrictions).
You can also use modules to specify which exceptions are to be rescued
(ruby-core:10618), allowing you to create rich exception hierarchies which
might be useful in some scenario:
Read more...
Read: Rich exception hierarchies, multiple inheritance in Ruby