An exception is an object that represents some kind of exceptional condition; it indicates that something has gone wrong. This could be a programming error—attempting to divide by zero, attempting to invoke a method on an object that does not define the method, or passing an invalid argument to a method. Or it could be the result from some kind of external condition—making a network request when the network is down, or trying to create an object when the system is out of memory.
When one of these errors or conditions occurs, an exception is
raise
d (or throw
n). By default, Ruby programs terminate when an
exception occurs. But it is possible to declare exception handlers.
An exception handler is a block of code that is executed if an
exception occurs during the execution of some other block of code.
In this sense, exceptions are a kind of control statement. Raising
an exception transfers the flow-of-control to exception handling
code. This is like using the break
statement to exit from a loop.
As we’ll see, though, exceptions are quite different from the break
statement; they may transfer control out of many enclosing blocks
and even up the call stack in order to reach the exception handler.
Ruby uses the Kernel method raise
to raise
exceptions, and uses a
rescue
clause to handle exceptions. Exceptions raise
d by raise
are
instances of the Exception class or one of its many subclasses. The
throw
and catch
methods described earlier in this chapter are not
intended to signal and handle exceptions, but a symbol thrown by
throw
propagates in the same way that an exception raise
d by raise
does. Exception objects, exception propagation, the raise
method,
and the rescue
clause are described in detail in the subsections
that follow.