# 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 forrescue
RuntimeError
– default forraise
Exception
- is a parent of all of them
Let your exceptions be all caught and and properly handled 👍