Rescuing exceptions in Ruby 
Tags: ruby, exceptions, beginners, learning
Published: 2018-04-11 08:12:54


---
cover_image: https://blog.appsignal.com/images/blog/2018-04/rescue.jpg
title: Rescuing exceptions in Ruby 
published: true
description: A raised exception can be rescued to prevent it from crashing your application once it reaches to top of the call stack. In this article, we'll examine different ways to rescue exceptions.
tags: ruby, exceptions, beginners, learning
canonical_url: https://blog.appsignal.com/2018/04/10/rescuing-exceptions-in-ruby.html
---

A raised [exception](https://blog.appsignal.com/2018/03/13/exceptions-in-ruby.html) can be rescued to prevent it from crashing your application once it reaches the top of the [call stack](https://blog.appsignal.com/2018/02/06/reading-and-understanding-ruby-stack-traces.html). In Ruby, we use the `rescue` keyword for that.

When rescuing an exception in Ruby, you can specify a specific error class that should be rescued from.

``` ruby
begin
  raise 'This exception will be rescued!'
rescue StandardError => e
  puts "Rescued: #{e.inspect}"
end
```

*Note*: When using `raise` without specifying an exception class, [Ruby will default to `RuntimeError`](https://blog.appsignal.com/2018/03/13/exceptions-in-ruby.html).

Besides specifying a single exception class to rescue, you can pass an array of exception classes to the `rescue` keyword. This will allow you to respond to multiple errors in the same way.

``` ruby
begin
  raise 'This exception will be rescued!'
rescue StandardError, AnotherError => e
  puts "Rescued: #{e.inspect}"
end
```

Multiple `rescue` blocks can be used to handle different errors in different ways. This can be useful when working with a library that produces different exceptions for different scenarios.

``` ruby
begin
  raise 'This exception will be rescued!'
rescue StandardError => e
  puts "Rescued: #{e.inspect}"
rescue AnotherError => e
  puts "Rescued, but with a different block: #{e.inspect}"
end
```

## The exception hierarchy

Ruby’s exception hierarchy is used to differentiate between different types of errors, while giving you the ability to rescue from a group of errors without specifying all of them.

Although libraries can define their own exception subclasses, the list of built-in [exception subclasses](http://ruby-doc.org/core-2.5.0/Exception.html) on Ruby 2.5 looks like this:

```
- NoMemoryError
- ScriptError
    - LoadError
    - NotImplementedError
    - SyntaxError
- SecurityError
- SignalException
    - Interrupt
- StandardError (default for `rescue`)
    - ArgumentError
        - UncaughtThrowError
    - EncodingError
    - FiberError
    - IOError
        - EOFError
    - IndexError
        - KeyError
        - StopIteration
    - LocalJumpError
    - NameError
        - NoMethodError
    - RangeError
        - FloatDomainError
    - RegexpError
    - RuntimeError (default for `raise`)
    - SystemCallError
        - Errno::*
    - ThreadError
    - TypeError
    - ZeroDivisionError
- SystemExit
- SystemStackError
- fatal (impossible to rescue)
```

When omitting the exception class in a `rescue` block, `StandardError` is assumed. Because `ArgumentError` and `NoMethodError` are subclasses of `StandardError`, these are rescued from when they occur in the block.

A good example of how the exception hierarchy works is `SystemCallError`, which is a low-level platform-dependent exception class. It’s seen most often when reading or writing to files.

Ruby’s `File.read` method will raise an exception if it fails to read the file. That can happen because of a number of reasons, like the file not existing or the program not having the correct permissions to read it. 

Since these problems are platform-dependent, Ruby can raise different exceptions depending on what kind of operating system is running on the machine. For low-level errors like this, Ruby implements a different list of `Errno::*`-exceptions for each platform.

All of these `Errno::*` exceptions are subclasses of `SystemCallError`. Although they’re platform-specific, they can still be used in a `rescue` block by rescuing from `SystemCallError`.

``` ruby
begin
  File.read("does/not/exist")
rescue SystemCallError => e
  puts "Rescued: #{e.inspect}"
end
```

## Swallowing exceptions

Usually, it’s best to be as specific as possible when rescuing exceptions, to prevent unintentionally swallowing exceptions.

``` ruby
image = nil

begin
  File.read(image.filename)
rescue
  puts "File can't be read!"
end
```

In this example, the `image` variable is `nil`, so it raises a `NoMethodError` when we try to call `#filename` on it (``NoMethodError: undefined method `filename' for nil:NilClass``). Because every `StandardError` subclass is rescued from (including `NoMethodError`), the exception is swallowed and the “File can’t be read!”-message is printed. This hides a possible bug in the code.

*Note*: Although it’s possible, using the `Exception` superclass in a `rescue` block is [highly discouraged](https://blog.appsignal.com/2016/10/18/ruby-magic-exceptions-primer.html).

Have any questions about raising or rescuing exceptions in Ruby? Please don't hesitate to let us know at [@AppSignal](https://twitter.com/appsignal). Of course, we’d love to know how you liked this article, or if you have another subject you’d like to know more about.