Why Isn't Ruby Rescuing My Exception?
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!
Comments
Just a tip; you can define your own exceptions like this:
MyApp::Error = Class.new(StandardError)
One benefit being no ugly trailing ‘end’. Also, and I know the point was to illustrate the idea, but try to be more specific: Error could be anything, WidgetFailureError is much more descriptive. Then:
module MyApp
WidgetFailureError = Class.new(StandardError)
class Widget
…
…
Nice find though.