Ruby exceptions: tips & tricks

Jokūbas - Nov 2 - - Dev Community

Exceptions are unexpected events that disrupt an application’s flow. Ruby’s exception-handling features make it easy to manage these errors, ensuring applications remain stable and user-friendly.

Here's an example of common exception handling flow in Ruby:

begin
  do_something # may raise an exception
  1/0 # raises an exception
rescue ZeroDivisionError => e
  # `ZeroDivisionError` exception handler
else
  # If no exceptions were raised
ensure
  # Code which always gets executed
end
Enter fullscreen mode Exit fullscreen mode

In this article, I’ll share a few tips on effectively handling exceptions in Ruby to keep your applications running smoothly.

fail with error

fail is a lesser-known keyword for raising errors in an application. However, it adds clarity to the code when you want it to explicitly fail and the program to exit.

Let's see an example:

begin
  fail "The weather is too bad for this code to work."
rescue
  puts "I'll try tomorrow."
  exit 0
end
Enter fullscreen mode Exit fullscreen mode

In this example, fail raises an error just like raise does. However, fail conveys a clearer intention from the developer for the application to fail.

rescue with multiple exceptions

rescue statement shares simillar syntax to case operator.

case foo
when Number, Decimal
  puts "It is a number"
when String
  puts "It is a string"
end

begin
  do_something
rescue NoMethodError, NameError
  puts "Method or variable is not defined"
rescue RuntimeError
  puts "Runtime error occured"
end
Enter fullscreen mode Exit fullscreen mode

This allows for clear handling of various error scenarios while maintaining readability in the code.

Rescueing from Exception

The Exception class is the base of Ruby's exception hierarchy. Therefore, when you rescue Exception, you are effectively rescuing from all Ruby built-in exceptions, including its subclasses like SyntaxError, LoadError, and Interrupt.

begin
  do_something
rescue Exception => e # bad
rescue => e # bad
end
Enter fullscreen mode Exit fullscreen mode

Exception#cause

In Ruby, we can always rescue and raise another exception, which is a common pattern. The Exception#cause method allows you to check if an exception was raised by another exception, and if so, it enables you to trace it back, making it easier to debug the code.

begin
  begin
    1/0
  rescue
    raise RuntimeError
  end
rescue => e
  puts e.class
  puts e.cause.class
end
# Output:
RuntimeError
ZeroDivisionError
Enter fullscreen mode Exit fullscreen mode

Current exception with $!

Ruby stores current exception in a $! variable which you can access in a code or whilst in a debuggig session in console.

begin
  raise RuntimeError, "It's hammertime"
rescue RuntimeError
  puts $!.message
end
# Outputs:
"It's hammertime"
Enter fullscreen mode Exit fullscreen mode

In this short post, we explored several tips for effective exception handling in Ruby. Using fail for clear error signaling, managing multiple exceptions with rescue, and leveraging Exception#cause for tracing errors are all strategies that enhance code readability and maintainability.

Thank you for reading and see you next time 🚀

. .