# RuntimeError < StandardError < Exception < Object
begin
require 'does/not/exist'
rescue Exception => e
"it is an Exception"
end
# => "it is an Exception"
begin
require 'does/not/exist'
rescue StandardError => e
"it is an Exception"
end
# => LoadError: cannot load such file -- does/not/exist
What is the difference in results between this
raise "Oups" rescue "Hi"
and this?
require 'does/not/exist' rescue "Hi"
And why the results are different. Let’s figure it out step by step.
It turns out that a rescue clause without an explicit Exception class will rescue all StandardErrors (and inherited ones).
I.e., if we just raise with some string, the plain rescue will catch it
def foo
raise "Oups"
end
foo rescue "Hello" #=> "Hello"
because the raise "some string" raises RuntimeError which inherits from StandardError.
But if we raise an Exception, it won’t catch it, and we will have it raised.
def foo
raise Exception
end
foo rescue "Hello" #=> Exception: Exception
Here is another good example from Ruby’s documentation:
require 'does/not/exist' rescue "Hi" # => LoadError
The rescue does not catch it because the LoadError is inherited from Exception (via ScriptError),
not from StandardError.
LoadError < ScriptError < Exception
If you need to rescue any error type/exception, it can be done like this:
begin
# any error type/exception
rescue Exception => e
"I will catch all of you"
end
Let’s check this out by raising different types explicitly.
E.g., a descendant of Exception like LoadError < ScriptError < Exception:
begin
raise LoadError
rescue Exception => e
"caught"
end
# => "caught"
E.g., a descendant of StandardError like FiberError < StandardError:
begin
raise FiberError
rescue Exception => e
"caught"
end
# => "caught"
E.g., a descendant of RuntimeError like FrozenError < RuntimeError < StandardError:
begin
raise FrozenError
rescue Exception => e
"caught"
end
# => "caught"
And just plain raise:
begin
raise "some explanation"
rescue Exception => e
"caught"
end
# => "caught"
As you can see, no matter what type is raised, it is always caught with rescue Exception.
Here is a shortcut to remember:
StandardError– default forrescueRuntimeError– default forraiseException- is a parent of all of them
Let your exceptions be all caught and and properly handled 👍