In Ruby, exception handling is a process which describes a way to handle the error raised in a program. Here, error means an unwanted or unexpected event, which occurs during the execution of a program, i.e. at run time, that disrupts the normal flow of the program’s instructions. So these types of errors were handled by the rescue block. Ruby also provides a separate class for an exception that is known as an Exception class which contains different types of methods.
The code in which an exception is raised, is enclosed between the begin/end block, so you can use a rescue clause to handle this type of exception.
Syntax:
begin
raise
# block where exception raise
rescue
# block where exception rescue
end
Example:
def raise_and_rescue
begin
puts 'This is Before Exception Arise!'
raise 'Exception Created!'
puts 'After Exception'
rescue
puts 'Finally Saved!'
end
puts 'Outside from Begin Block!'
end
raise_and_rescue
|
Output:
This is Before Exception Arise!
Finally Saved!
Outside from Begin Block!
Explanation: In the above program, an exception is raised in the begin block (raise block) which interrupt the flow of execution of the program. To overcome this situation, use the rescue block to handle the raised exception. When rescue block is used, it handles the exception and continues the execution of the program.
Note: Multiple rescue clauses can be used in the same program which means if an exception is not handled by the first rescue clause, then another rescue clause will definitely handle the exception. If no rescue clause match, or if an exception occurs outside the begin/end block, then Ruby moves up to the stack and looks for an exception handler in the caller.
The statements used in Exceptions are:
- retry Statement: This statement is used to execute the rescue block again from the beginning after capturing the exception.
Syntax:
begin
# block where exception raise
rescue
# block where an exception is captured
retry
# this statement restarts the rescue
# block from the beginning
end
Example:
begin
raise 'Exception Created!'
puts 'After Exception'
rescue
puts 'Finally Saved!'
retry
end
|
Output:
Finally Saved!
Finally Saved!
Finally Saved!
Finally Saved!
Finally Saved!
Finally Saved!
.
.
.
.
Note: Be careful while using retry statement because it may result into infinite loop.
- raise Statement: This statement is used to raise an exception.
Syntax:
raise
This syntax is used to re-raise the current exception. It is generally used by the exception handler where an exception is interrupted before passing it on.
raise "Error Message"
This syntax is used to create a RuntimeError exception and it raises up the call stack.
raise ExceptionType, "Error Message"
In this syntax, the first argument is used to create an exception and then set the message in the second argument.
raise ExceptionType, "Error Message" condition
In this syntax, the first argument is used to create an exception and then set the message in the second argument. You can also set a condition statement to raise an exception.
Example:
begin
puts 'This is Before Exception Arise!'
raise 'Exception Created!'
puts 'After Exception'
end
|
Output:
This is Before Exception Arise!
Exception Created!
- ensure Statement: This statement ensures that required instructions will execute at the end of the code, whether the exception raise or raised exception is rescued, or the program terminates due to an uncaught exception. This block always gives output. This block is placed over the rescue block.
Syntax:
begin
# exception raise
rescue
# exception rescue
ensure
# this block always executes
end
Example:
begin
raise 'Exception Created!'
puts 'After Exception'
rescue
puts 'Finally Saved!'
ensure
puts 'ensure block execute'
end
|
Output:
Finally Saved!
ensure block execute
- else Statement: This statement is present in between the rescue block and ensure block. This block only executes when no exception is raised.
Syntax:
begin
rescue
# exception rescue
else
# this block executes when no exception raise
ensure
# this block always executes
end
Example:
begin
puts 'no Exception raise'
rescue
puts 'Finally Saved!'
else
puts 'Else block execute because of no exception raise'
ensure
puts 'ensure block execute'
end
|
Output:
no Exception raise
Else block execute because of no exception raise
ensure block execute
Catch and Throw in Exception Handling
In Ruby, catch and throw blocks are the lightweight mechanism for error handling and used to jump from the exception when there is no additional work is available in the program.
The catch block is used to jump out from the nested block and the block is labeled with a name. This block works normally until it encounters with the throw block. catch and throw method will work faster than raise and rescue method. When the throw statement is encountered, Ruby will check the call stack for the catch statement with the related symbol. The throw statement never executes and always return nil.
Syntax:
throw :label_name
# this block will not be executed
catch :label_name do
# matching catch will be executed when the throw block encounter
end
You can also apply a condition in catch and throw statement as shown below:
throw :label_name condition
# this block will not be executed
catch :label_name do
# matching catch will be executed when the throw block encounter
end
Example:
def catch_and_throw(value)
puts value
a = readline.chomp
throw :value_e if a == "!"
return a
end
catch :value_e do
number = catch_and_throw( "Enter Number: " )
end
|
Input:
Enter Number: 1
Output:
1
Input:
Enter Number: !
Output:
nil
Explanation: In the above example the catch_and_throw method is used to print the value enter in the catch statement. If the user enters a number, then it will print number, but if the user enters !, then it will give you nil. Because the throw statement has effectively never executed.