There are many built-in error classes in Ruby and Rails. Most of these errors are subclasses of Ruby’s StandardError. You can find more information in the relevant Ruby docs.

Instead of…

…rescuing Exception.

defyour_method# do somethingrescueException=>e# saved ALL THE THINGSend

Or…

…a non-specific rescue that implicitly rescues StandardError.

defyour_method# do somethingrescue=>e# saved StandardError and all subclassesend

Use…

…rescue on a specific named error.

defyour_method# do somethingrescueSpecificProblemError=>e# saved only what you meant torescueAnotherProblemError=>e# saved a different kind of errorend

But why?

Ruby’s Exception is the parent class to all errors. “Great” you might say, “I want to catch all errors”. But you don’t.

Exception includes the class of errors that can occur outside your application. Things like memory errors, or SignalException::Interrupt (sent when you manually quit your application by hitting Control-C). These are errors you don’t want to catch in your application as they are generally serious and related to external factors. Rescuing Exception can cause very unexpected behaviour.

StandardError is the parent of most Ruby and Rails errors. If you catch StandardError you’re not introducing the problems of rescuing Exception, but it is not a great idea. Rescuing all application-level errors might cover up unrelated bugs you don’t know about.

The safest approach is to rescue the error (or errors) you are expecting and deal with the consequences of that error inside the rescue block.

In the event of an unexpected error in your application you want to know that a new error has occurred and deal with the consequences of that new error inside its own rescue block.

Being specific with rescue means your code doesn’t accidentally swallow new errors. You avoid subtle hidden errors that lead to unexpected behaviour for your users and bug hunting for you.

Don’t miss my next post, sign up to the One Ruby Thing email and get my next post in your inbox.