» What is it?

The Exception class in Ruby is what all other errors inherit from; it's the top level exception, and it should very rarely — if ever — be rescued. In fact, some obscure bugs can actually be caused by rescuing Exception in the wrong place.

» Why you should never rescue Exception

Exception has a number of subclasses; some are recoverable while others are not. All recoverable errors inherit from the StandardError class, which itself inherits directly from Exception .

The other direct-descendants of Exception and their children are used by Ruby internally for other purposes. In many cases they are unrecoverable exceptions; the Ruby program cannot recover gracefully and must crash when they are encountered.

When you rescue Exception , you also rescue all of its children — including all of the unrecoverable exceptions:

begin do_something_risky () rescue Exception => e # Don't do this. This will swallow every single exception. Nothing gets past it. end

» Ruby's Internal Exceptions

There are only a handful of internal Exceptions that Ruby uses, and like we already mentioned, rescuing all of them indiscriminately is usually not a good idea (although rescuing some of them individually is fairly common). These are Ruby's internal exceptions.

NoMemoryError is raised by Ruby when memory allocation fails. This does not mean that the system is out of memory; rather, it indicates that Ruby attempted to initialize an object that would consume more memory than the system allows.

On 64 bit systems, for example, the maximum allowed value of a String is 2**63 - 1 . We can see that Ruby will not allow us to allocate a string longer than that:

s = String . new ( "1" * ( 2 ** 63 ))

raises the exception:

RangeError: bignum too big to convert into `long'

However, while Ruby is capable of handling a String slightly shorter than the maximum, available memory is often a limiting factor:

s = String . new ( "1" * ( 2 ** 62 ))

raises the exception:

NoMemoryError: failed to allocate memory

This exception is raised when a file required fails to load:

require 'these/are/not/the/scripts/youre/looking/for'

raises the exception:

LoadError: no such file to load -- these/are/not/the/scripts/youre/looking/for

A common pattern in Ruby is to rescue LoadError specifically (which is OK, since it's not rescuing any other exceptions) to load an optional dependency which may not be present:

being require 'rack' rescue LoadError puts "Rack is not present, but it's OK because we expected it" end

Because of this, if your Ruby application is crashing due to a missing constant belonging to a file which has been required, it's possible that the LoadError is being rescued improperly.

NotImplementedError is raised when a feature is not implemented on the current platform. For example, if the underlying operating system or Ruby runtime doesn't support forking processes (via the fork system call), Ruby will raise NotImplementedError .

SyntaxError is raised when Ruby encounters code with an invalid syntax:

eval ( "puts('Forgot something)" )

raises the following exception:

SyntaxError: (eval):1: unterminated string meets end of file

SecurityError is part of Ruby's security model; it's raised when a potentially unsafe operation is attempted.

For example, every Ruby object that comes from an external source (such as a String read from a file, or an environment variable) is automatically marked as being "tainted". When your Ruby program works with tainted objects, it may raise the SecurityError exception when an operation is not permitted, such as attempting to eval a tainted String :

$SAFE = 1 foo = "puts 'hello world'" foo . taint eval ( foo )

raises the exception:

SecurityError: Insecure operation - eval (SecurityError)

Interrupt is raised when an interrupt signal is received from the operating system; typically when a user presses Control-C:

puts "Press CTRL-C to quit the loop" loop {}

raises the exception:

Interrupt

SystemExit is raised by exit to initiate the termination of the Ruby program:

begin exit ( 1 ) rescue SystemExit => e puts "the ruby program is exiting with status #{ e . status } " raise end

prints the output:

the ruby program is exiting with status 1

and exits with status 1.

If you rescue SystemExit without re-raising the exception, your Ruby program will continue to execute until it exits at the next opportunity, and the status code may be be different from the one that was rescued:

begin exit ( 1 ) rescue SystemExit => e puts "the ruby program is exiting with status #{ e . status } " end exit ( 0 )

prints the output:

the ruby program is exiting with status 1

but exits with status 0.

SystemStackError is one of the more popular exceptions across all programming languages. If you've ever gotten a cryptic "stack level too deep" error in Ruby, you've encountered a SystemStackError exception:

def malcovitch_malcovitch malcovitch_malcovitch end malcovitch_malcovitch

raises the exception:

SystemStackError: stack level too deep

fatal is an Exception that Ruby raises when it encounters a fatal error and must exit. It is impossible to rescue fatal , and it's impossible to raise it artificially.

» If you must...

First of all, we'll say it again: don't rescue the Exception class in Ruby. If you must rescue Exception , such as for error reporting, always re-raise the exception promptly:

begin do_something_risky () rescue Exception => e logger . fatal ( "Encountered an Exception: #{ e } " ) raise e # <-- always do this! end