Blog |

How to Handle Exceptions in Ruby with Rescue

How to Handle Exceptions in Ruby with Rescue
Table of Contents

Ruby has a robust error handling mechanism called rescue. The way it works is the keyword rescue specifies an exception handler that will catch and handle any exceptions that are raised in the begin block, the code block preceding the rescue block that may cause an exception.

Here’s how it looks:

begin
  # code that may raise an exception
rescue
  # code to handle the exception
end

When an exception occurs in the begin code block, Ruby transfers control to the rescue block and executes the code within it. And when no exception is raised, the rescue block is skipped and the program continues executing normally.

Example: Using Rescue to Handle An Exception

In this example, the divide method takes two arguments, a and b , and attempts to divide a by b . If b is zero, a ZeroDivisionError exception is raised. To handle this exception, we use a begin block followed by a rescue block. The rescue block catches the ZeroDivisionError exception and prints an error message to the console. It then sets the result to nil and returns it.

def divide(a, b)
  begin
    result = a / b
  rescue ZeroDivisionError => e
    puts "Error: #{e.message}"
    result = nil
  end
  return result
end

puts divide(10, 2)   # Output: 5
puts divide(10, 0)   # Output: Error: divided by 0
                     #         nil

Output:

5
Error: divided by 0

The code block that might raise an exception is placed within the begin block, and the rescue block is used to handle the exceptions raised in the begin block.

Common Methods of Handling Exceptions in Ruby

The rescue keyword can be used in different ways to handle exceptions in Ruby. Let's look at some of the most common ways:

1. Handling a Specific Exception

If we want to handle a specific exception, we can specify the type of exception we want to handle in the rescue block.

begin
  # code that may raise a ZeroDivisionError exception
rescue ZeroDivisionError
  # code to handle the ZeroDivisionError exception
end

In the above code, the rescue block will only catch ZeroDivisionError ; if any other exception is raised, it will not be caught by this block.

2. Handling Multiple Exceptions

We can also handle numerous exceptions in a single rescue block by separating them with commas.

begin
  # code that may raise an exception
rescue ZeroDivisionError, TypeError
  # code to handle the ZeroDivisionError or TypeError exception
end

The rescue block in the preceding code will only catch ZeroDivisionError and TypeError; any other exception raised will not be caught by this block.

3. Handling All The Exceptions

Now this is an interesting point. All the exceptions and errors fall under the Exception class, but rescuing the Exception class will rescue every exception, and this might cause some problems, for instance:

  • SignalException::Interrupt: If we rescue this, we can't exit our app by hitting ctrl+c.
  • NoMemoryError:Raised when our program keeps running after consuming all the RAM.
begin
  #code that may raise an exception
rescue Exception => e
  # This will swallow every single exception including system level exceptions. Nothing gets past it. 
end

It's not a good practice to rescue system-level exceptions such as those above. We only want to catch all the application-level errors that our code raises, and all the exceptions that we should care about inherit from the StandardError class.

The StandardError class is the parent class of all the standard error classes in Ruby, so it will catch any exception that is derived from it:

begin
  # code that may raise an exception
rescue StandardError
  # code to handle any exception
end

4. Using An Else Block

We can also use an else block in our code, just after the rescue block, to specify the code that should be executed if no exception is raised. In this example, the else block will be executed if no exception is raised in the begin block.

begin
  # code that may raise an exception
rescue StandardError
  # code to handle any exception
else
  # code to execute if no exception is raised
end

In conclusion, the rescue keyword is an essential part of Ruby's exception handling mechanism. It allows developers to gracefully handle exceptions and recover from errors, preventing unexpected program crashes. By understanding how to use rescue to handle specific types of exceptions, multiple exceptions, or all exceptions, you can write more robust and reliable Ruby code.

At the same time, when using rescue, it's important to carefully consider which exceptions to handle and how to handle them. Catching and handling every exception indiscriminately can lead to errors being masked and difficult to diagnose. It's also a good practice to make sure that any code in your rescue block is well-tested and doesn't introduce new bugs.

Track, Analyze and Manage Errors With Rollbar

Ruby provides a rich set of tools for developing and debugging code, but errors can still occur during development or execution. Being able to track, analyze, and manage errors in real-time can help you proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Ruby errors easier than ever. Try it today!

Related Resources

"Rollbar allows us to go from alerting to impact analysis and resolution in a matter of minutes. Without it we would be flying blind."

Error Monitoring

Start continuously improving your code today.

Get Started Shape