Exceptions in Ruby

Jeff Jeff Kreeftmeijer on

An exception is a special data structure that holds information about an exceptional condition happening in your application. Exceptions are signals sent when your program can’t continue running because it doesn’t know how to deal with a specific situation. In Ruby, we call sending such a signal raising an exception.

raise 'this is an exception'

puts "This message won't be printed."

The quickest way to see an exception in action is to raise one yourself. By using the raise method with a message, Ruby will create a RuntimeError with the passed text as its description. It will also add a stack trace that points to where the exception was raised from in your code.

$ ruby raise.rb
raise.rb:1:in `<main>': this is an exception (RuntimeError)

When running the example script above, you’ll notice that, as promised, the message isn’t printed after the exception is raised. That’s because unhandled exceptions halt execution of your program by causing a crash. This is to make sure your application doesn’t keep running after failing to complete one of its tasks.

Different types of exceptions

Internally, Ruby raises exceptions when things go wrong. For example, you’ll get an exception when trying to devide a number by zero.

irb(main):001:0> 42/0
ZeroDivisionError: divided by 0
        from (irb):1:in `/'
        from (irb):1
        from /Users/jeff/.asdf/installs/ruby/2.3.0/bin/irb:11:in `<main>'

In this case, the exception’s type is ZeroDivisionError, instead of the RuntimeError we saw before. There are dozens of exception types to form Ruby’s exception hierarchy, and they’re all raised in different situations.

RuntimeError is a more generic exception class, but there are more specific examples. A NoMethodError gets raised when trying to call a method that doesn’t exist, and an ArgumentError notes that the wrong arguments are passed to an existing method, for example.

Rescueing exceptions

Most applications require the ability to recover from exceptions. In a web application, an error can happen when a user submits faulty data in a form. This should result in an error message being displayed to the user instead of crashing the whole web server.

In a case like that, an exception might get raised, but it will get rescued by the web server before reaching the top of the call stack, which prevents the exception from crashing the application.

  raise 'this is an exception'
rescue RuntimeError => exception
  puts "Exception rescued: #{exception.inspect}"
  # => "Exception rescued: #<RuntimeError: this is an exception>"

puts "This message *will* be printed."

By wrapping the example from before in a begin/rescue block, the exception won’t get raised, and it won’t crash our app. Instead, the rescue-block gets executed, which prints a message explaining the exception was thwarted, in this case. Also, because this prevents our app from crashing, the last message will get printed.

This example specifically rescues from RuntimeErrors, so any other error won’t get caught. Being specific about which errors are rescued is convenient, because it’ll allow you to do different things when different errors occur. Also, it’s important to make sure not to rescue too many exceptions.

For a more in-depth primer on exception handling, and some tips on how to properly rescue exceptions, check out our exceptions primer on Ruby Magic.

Have any questions about raising or catching exceptions in Ruby? Please don’t hesitate to let us know at @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.

5 favorite Ruby articles

10 latest Ruby articles

Go back
Ruby magic icon

Subscribe to

Ruby Magic

Magicians never share their secrets. But we do. Sign up for our Ruby Magic email series and receive deep insights about garbage collection, memory allocation, concurrency and much more.

We'd like to set cookies, read why.