I was really confused yesterday when rescue refused to catch my exception.

begin user.update # raises a MyApp::Error rescue => error # but was not rescued end

Isn’t rescue supposed to rescue everything? Actually, no. Without specifying which exception classes to catch, rescue will only catch exceptions that inherit from StandardError .

That means…

begin rescue end

…is really just short-hand for:

begin rescue StandardError end

Some folks recommend explicitly writing rescue StandardError whenever you want a plain rescue . I don’t have a strong opinion, because once you know why Ruby behaves the way it does, you won’t be caught off guard.

Why does Ruby default to only catching exceptions that inherit from StandardError ? Let’s look at some examples from the Exception class hierarchy.

Events that should stop your program (like the user hitting ctrl-c in the terminal or require failing to find a file) inherit directly from Exception . Problems that might be recoverable (like calling fall\_in\_love on nil or passing "chocolate" to Time.parse ) inherit from StandardError . This means that our code should almost always inherit from StandardError .

Sure enough, that was my bug. I changed…

class MyApp::Error < Exception end

…to…

class MyApp::Error < StandardError end

…and the error was properly caught!