---
title: Don't Inline-Rescue in Ruby
teaser: 'Do not use the inline version of `rescue` in Ruby, unless you REALLY know
  what you are doing.

  '
tags: ruby,new bamboo,web
author: Pablo Brasero
published_on: 2015-09-23
---

_This post was originally published on the New Bamboo blog, before [New Bamboo
joined thoughtbot in London][new-bamboo-thoughtbot]._

---

We are currently hiring at [New Bamboo]. As part of the process, we send
candidates a code test to complete at their own leisure. I won’t reveal any
details here, but it’s nothing special.

Nevertheless, I have personally reviewed a bunch of these code tests, and
there’s something that has caught my attention. A number of applicants
misunderstand the usage of the inline `rescue` construct in Ruby. Not a whole
lot of them, but enough that I felt compelled to write this piece in order to
help other people out there.

What I am seeing is code like the following:

```ruby
do_something rescue SomeException
```

I assume applicants read that as “if `SomeException` is raised, rescue it and
just carry on as if nothing had happened”. Unfortunately, this is not the case.
I’ll show with a different example. See this:

```ruby
do_something rescue nil
```

What the above does is:

1. It calls the method `do_something`
2. If that raised an exception, it’s rescued immediately. The line evaluates to
  `nil`
3. If no exception was raised, the line evaluates to the return value of
  `do_something`

The following is equivalent:

```ruby
begin
  do_something
rescue
  nil
end
```

Five lines with their indentation against a clever one-liner. Tempting! If you
know that `do_something` may raise an exception, you use an inline `rescue` to
quickly stop that and continue. Isn’t that neat?

Except that it’s a headache waiting to happen. Consider this code:

```ruby
def someting_is_wrong?
  rand < 0.01 # Good 99% of the time
end

def do_something
  if something_is_wrong?
    raise MyIgnorableException
  else
    "foo"
  end
end

begin
  do_something
rescue
  nil
end
```

This code looks ok. However, when we run it, something is amiss. It always
returns `nil`. We expected it to fail (return `nil`) only in 1% percent of the
cases, but it’s actually failing 100% of the time. What’s going on?

Well, that we misspelled the name of the first method, that’s what. Read again:
`someting_is_wrong?`. An “h” is missing.

We are calling a method that doesn’t exist. This raises a `NoMethodError`, which
bubbles up to the `rescue`, which in turn ends up rescuing more than we wanted.
Remember that an unqualified `rescue` will catch any exceptions that inherit
from `StandardError`. That is dangerous, as it is likely that there will be
other problems.

Instead we should use the following invocation:

```ruby
begin
  do_something
rescue MyIgnorableException
  nil
end
```

This time we get a `NoMethodError` straight away. We notice the problem, fix it,
and continue on our merry way, safe in the knowledge that we'll be notified of
any unforeseen problems.

In summary, there are two problems with inline `rescue` of exceptions:

- The syntax can be misleading, making you think that it’s rescuing only a
  specific type of exception, when it’s not. It’s rescuing any type of exception
  (as long as it inherits from `StandardError`), then evaluating the expression
  that follows it
- Rescuing exceptions without sensible filtering will make you miss other
  problems that you didn’t expect

Therefore, here are two pieces of advice:

- Never use the unfiltered version of `rescue`
- Never use the inline `rescue`, as it’s effectively an unfiltered `rescue`

OK, I say “never”, but Avdi Grimm could come up with a decent use case for the
inline `rescue`. Rather than outlining it here, stealing Avdi’s thunder, and
making this longer than it needs to be, I’m just going to link to the screencast
where he explains it better than I can, in just 3:17 minutes. It’s issue \#22 of
his excellent [Ruby Tapas], and it’s available for free at his blog: [Ruby Tapas
\#22 - Inline Rescue][tapas-22].

Happy hacking!

[new-bamboo-thoughtbot]: https://thoughtbot.com/blog/new-bamboo-joins-thoughtbot-in-london
[New Bamboo]: https://www.new-bamboo.co.uk/
[Ruby Tapas]: http://www.rubytapas.com/
[tapas-22]: http://www.virtuouscode.com/2012/11/19/rubytapas-022-inline-rescue/
