Error Handling in Ruby: Part I
In this article, we’re going to explore the following topics:
- what is an error in Ruby?
- how to throw & catch an error?
- errors & magic variables
What’s an error in Ruby?
As Ruby is a fully object-oriented language, an error is an instance of a class that includes the Exception
class in its ancestor chain
irb> RuntimeError.ancestors.include? Exception
=> true
irb> NoMethodError.ancestors.include? Exception
=> true
That’s why an error is commonly called an “exception” in Ruby.
NB: feel free to have a look to the Ruby Object Model: Part I article if you’re unfamiliar with the
ancestor chain
in Ruby.
As an error is a class, Ruby provides a set of methods to deal with an occurring error.
These methods are defined in the Exception
class and used by all of its children.
For example, the Exception#message
method returns the message associated with the error when the Exception#backtrace
method returns the error backtrace.
Feel free to browse the official documentation for further information.
How to throw & catch an error?
Kernel#raise
is in charge of raising errors in Ruby
irb> raise 'an error occurred'
RuntimeError: an error occurred
irb> raise NoMethodError, 'an error occurred'
NoMethodError: an error occurred
In the first call to Kernel#raise
, we can see that the method raises a RuntimeError
— as no error class is explicitly specified as an argument.
On the other hand, the second call to Kernel#raise
the raises a NoMethodError
— as we defined it as the first argument.
These exceptions can be caught by a rescue
clause within a begin...end
block
produces
NoMethodError: an error occurred
Here, the rescue
clause caught a NoMethodError
exception raised by the call to Kernel#raise
within the begin...end
block.
begin...end
is used to compartmentalize blocks of code depending on the possible errors that can occur for each of them
produces
ZeroDivisionError: divided by 0
NoMethodError: undefined method `odd?' for "my string":String
Note that in the first begin...end
block, the3 / 0
operation internally raised ZeroDivisionError
via the Integer#/
method.
Feel free to read the
Numbers and Class Hierarchy in Ruby
article if you are unfamiliar with theInteger
class and its ancestor chain.
It’s the same for the second begin...end
block where the BasicObject#method_missing
Ruby hook method raised NoMethodError
.
Feel free to read the
Metaprogramming: Ruby Hook Methods
article if you are unfamiliar with the hook methods in Ruby.
Errors & magic variables
Ruby provides 2 magic variables that are set when an exception is raised:
$!
which contains the raised exception$@
which contains the exception backtrace
produces
NoMethodError: undefined method `odd?' for "my string":String
/workspace.rb:87:in `eval'
/workspace.rb:87:in `evaluate'
...
/bin/irb:11:in `<main>'
These variables are cleared — set to nil
— when the rescue
block ends.
Feel free to have a look to the Part II.
Ruby Mastery
We’re currently finalizing our first online course: Ruby Mastery.
Join the list for an exclusive release alert! 🔔
Also, you can follow us on x.com as we’re very active on this platform. Indeed, we post elaborate code examples every day.
💚