---
title: "Rescue's elegant trick for knowing which exceptions to catch"
published: "2017-01-10"
publisher: Honeybadger
author: Starr Horne
category: Ruby articles
tags:
  - Ruby
description: "You probably know how to ask Ruby to rescue specific exceptions. But how does Ruby know if a particular exception meets your criteria? In this article, we'll walk through Ruby's simple exception matching mechanism and see how we can use it to our advantage."
url: "https://www.honeybadger.io/blog/ruby-rescue-elegant-trick-for-knowing-which-exceptions-to-catch/"
---

If you've worked with Ruby's exceptions before, you know you can specify which exceptions get rescued and which are not:

```ruby
begin raise ArgumentError rescue ArgumentError # Rescues the `ArgumentError` end
```

...and you probably know that when you rescue a "parent" you rescue all of its "children" as well.

```ruby
begin raise ArgumentError rescue StandardError # Rescues `ArgumentError`, because it inherits from # `StandardError` end
```

When I say "parent" and "child" I'm simply referring to class inheritance. Somewhere deep in the Ruby source code there is something equivalent to this:

```
class ArgumentError < StandardError ... end
```

## An interesting trick

Here's my question: how does Ruby know if any given exception inherits from the class you specified?

The most obvious approach would be to use the `is_a?` or `kind_of?` method. We could imagine it looking like this:

```ruby
if the_exception.is_a?(StandardError) # do the rescue end
```

But that's not what happens. Instead, Ruby uses the more interesting `===` operator.

```ruby
if StandardError === the_exception # do the rescue end
```

If you've never used `a === b`, it usually answers the question "does a inherently belong to the group defined by b"? Here are some examples:

```ruby
(1..10) === 5             # true ('a'..'f') === "z"        # false String === "hello"        # true String === 1              # false /[0-9]{3}/ === "hello123" # true /[0-9]{3}/ === "hello"    # false
```

Because `===` is just an ordinary ruby method like `==`, we can define it ourself:

```ruby
class RedThings def self.===(thing) thing.color == :red end end
```

So, what do we know? We know that `rescue` uses `===` to determine which exceptions get rescued. And we know that we can define our own `===` method. That means we can create a class that decides on-the-fly which exceptions are rescued:

```ruby
class SevereMatcher def self.===(exception) exception.message =~ /severe/ end end begin raise RuntimeError, "Something severe happened" rescue SevereMatcher # rescues all exceptions with the word "severe" in # the message, regardless of class. end
```

Once you know this trick, the only limit is your imagination.

## Conclusion

I'll admit: you may not ever need to create a dynamic exception matcher. But this is a really interesting example of how a seemingly-trivial implementation detail like using `===` instead of `kind_of?` makes Ruby much more flexible and interesting.

---

## Try Honeybadger for FREE

Intelligent logging, error tracking, and Just Enough APM™ in one dev-friendly platform. Find and fix problems before users notice.

[Start free trial](https://app.honeybadger.io/users/sign_up)

[See plans and pricing](https://www.honeybadger.io/plans/)
