Exception
Handling¶ ↑
Exceptions are rescued in a begin
/end
block:
begin # code that might raise rescue # handle exception end
If you are inside a method, you do not need to use begin
or end
unless you wish to limit the scope of rescued exceptions:
def my_method # ... rescue # ... end
The same is true for a class
, module
, and block
:
[0, 1, 2].map do |i| 10 / i rescue ZeroDivisionError nil end #=> [nil, 10, 5]
You can assign the exception to a local variable by using => variable_name
at the end of the rescue
line:
begin # ... rescue => exception warn exception.message raise # re-raise the current exception end
By default, StandardError
and its subclasses are rescued. You can rescue a specific set of exception classes (and their subclasses) by listing them after rescue
:
begin # ... rescue ArgumentError, NameError # handle ArgumentError or NameError end
You may rescue different types of exceptions in different ways:
begin # ... rescue ArgumentError # handle ArgumentError rescue NameError # handle NameError rescue # handle any StandardError end
The exception is matched to the rescue section starting at the top, and matches only once. If an ArgumentError
is raised in the begin section, it will not be handled in the StandardError
section.
You may retry rescued exceptions:
begin # ... rescue # do something that may change the result of the begin block retry end
Execution will resume at the start of the begin block, so be careful not to create an infinite loop.
Inside a rescue block is the only valid location for retry
, all other uses will raise a SyntaxError
. If you wish to retry a block iteration use redo
. See Control Expressions for details.
To always run some code whether an exception was raised or not, use ensure
:
begin # ... rescue # ... ensure # this always runs BUT does not implicitly return the last evaluated statement. end
You may also run some code when an exception is not raised:
begin # ... rescue # ... else # this runs only when no exception was raised AND return the last evaluated statement ensure # this always runs. # It is evaluated after the evaluation of either the `rescue` or the `else` block. # It will not return implicitly. end
NB : Without explicit return
in the ensure
block, begin
/end
block will return the last evaluated statement before entering in the ‘ensure` block.