"Never rescue Exception in Ruby!"

Maybe you've heard this before. It's good advice, but it's pretty confusing unless you're already in the know. Let's break this statement down and see what it means.

You probably know that in Ruby, you can rescue exceptions like so:

begin do_something() rescue => e puts e # e is an exception object containing info about the error.  end 

And you can rescue specific errors by providing the classname of the error.

begin do_something() rescue ActiveRecord::RecordNotFound => e puts e # Only rescues RecordNotFound exceptions, or classes that inherit from RecordNotFound end 

Every type of exception in Ruby is just a class. In the example above, ActiveRecord::RecordNotFound is just the name of a class that follows certain conventions.

This is important because when you rescue RecordNotFound, you also rescue any exceptions that inherit from it.

Why you shouldn't rescue Exception

The problem with rescuing Exception is that it actually rescues every exception that inherits from Exception. Which is....all of them!

That's a problem because there are some exceptions that are used internally by Ruby. They don't have anything to do with your app, and swallowing them will cause bad things to happen.

Here are a few of the big ones:

  • SignalException::Interrupt - If you rescue this, you can't exit your app by hitting control-c.

  • ScriptError::SyntaxError - Swallowing syntax errors means that things like puts("Forgot something) will fail silently.

  • NoMemoryError - Wanna know what happens when your program keeps running after it uses up all the RAM? Me neither.

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

I'm guessing that you don't really want to swallow any of these system-level exceptions. You only want to catch all of your application level errors. The exceptions caused YOUR code.

Luckily, there's an easy way to to this.

Rescue StandardError Instead

All of the exceptions that you should care about inherit from StandardError. These are our old friends:

  • NoMethodError - raised when you try to invoke a method that doesn't exist

  • TypeError - caused by things like 1 + ""

  • RuntimeError - who could forget good old RuntimeError?

To rescue errors like these, you'll want to rescue StandardError. You COULD do it by writing something like this:

begin do_something() rescue StandardError => e # Only your app's exceptions are swallowed. Things like SyntaxErrror are left alone.  end 

But Ruby has made it much easier for use.

When you don't specify an exception class at all, ruby assumes you mean StandardError. So the code below is identical to the above code:

begin do_something() rescue => e # This is the same as rescuing StandardError end 

Custom Exceptions Should Inherit from StandardError

So what does this mean for you if you're creating your own custom exceptions?

It means you should always inherit from StandardError, and NEVER from Exception. Inheriting from Exception is bad because it breaks the expected behavior of rescue. People will think they're rescuing all application-level errors but yours will just sail on through.

class SomethingBad < StandardError end raise SomethingBad 

The Exception Tree

Since Ruby's exceptions are implemented in a class heirarchy, it can be helpful to see it laid out. Below is a list of exception classes that ship with Ruby's standard library. Third-party gems like rails will add additional exception classes to this chart, but they will all inherit from some class on this list.

Exception NoMemoryError ScriptError LoadError NotImplementedError SyntaxError SignalException Interrupt StandardError ArgumentError IOError EOFError IndexError LocalJumpError NameError NoMethodError RangeError FloatDomainError RegexpError RuntimeError SecurityError SystemCallError SystemStackError ThreadError TypeError ZeroDivisionError SystemExit fatal 

Try Honeybadger for FREE

"I just want to say, after 21 years of working in web development, this was the easiest signup experience I've ever had. Amazing work." — Andrew McGrath
Start free trial
Easy 5-minute setup — No credit card required
author photo
Starr Horne

Starr Horne is a Rubyist and former Chief JavaScripter at Honeybadger. When she's not fixing bugs, she enjoys making furniture with traditional hand-tools, reading history and brewing beer in her garage in Seattle.

More articles by Starr Horne
An advertisement for Honeybadger that reads 'Move fast and fix things.'

"We love Honeybadger. Not only is it a fab tool and very affordable, they feel like a partner - whenever we needed help we got FIRST CLASS service."

Fix errors, eliminate performance bottlenecks, and dig into the details faster than ever before. With support for Ruby, Elixir, and 8 other languages, Honeybadger is the best way to gain real-time insights into your app’s health and performance.

Get started for free
Simple 5-minute setup — No credit card required