Ruby's Exception vs StandardError: What's the difference?

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.

"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
What to do next:
  1. Try Honeybadger for FREE
    Honeybadger helps you find and fix errors before your users can even report them. Get set up in minutes and check monitoring off your to-do list.
    Start free trial
    Easy 5-minute setup — No credit card required
  2. Get the Honeybadger newsletter
    Each month we share news, best practices, and stories from the DevOps & monitoring community—exclusively for developers like you.
    author photo

    Starr Horne

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

    More articles by Starr Horne
    Stop wasting time manually checking logs for errors!

    Try the only application health monitoring tool that allows you to track application errors, uptime, and cron jobs in one simple platform.

    • Know when critical errors occur, and which customers are affected.
    • Respond instantly when your systems go down.
    • Improve the health of your systems over time.
    • Fix problems before your customers can report them!

    As developers ourselves, we hated wasting time tracking down errors—so we built the system we always wanted.

    Honeybadger tracks everything you need and nothing you don't, creating one simple solution to keep your application running and error free so you can do what you do best—release new code. Try it free and see for yourself.

    Start free trial
    Simple 5-minute setup — No credit card required

    Learn more

    "We've looked at a lot of error management systems. Honeybadger is head and shoulders above the rest and somehow gets better with every new release."
    — Michael Smith, Cofounder & CTO of YvesBlue

    Honeybadger is trusted by top companies like:

    “Everyone is in love with Honeybadger ... the UI is spot on.”
    Molly Struve, Sr. Site Reliability Engineer, Netflix
    Start free trial