9

In Ruby, I want to do something special for a specific exception but not enough to have a specific rescue. What is the proper syntax to check for a specific exception within rescue?

Sample (non-working) code:

begin
   c = d
rescue => ex
  if ex == NameError
    puts 'NameError'
  else
    puts ex.message
  end
end

2 Answers 2

10

In your example ex is an instance of on exception, and will not give expected results when comparing to the class itself with the == operator, which is a Class object. You need to check the error's class against the actual class object.

# A NameError or an error that is a subclass of NameError
ex.is_a?(NameError)
ex.kind_of?(NameError)

# NameError ONLY, not even sub-classes of NameError
ex.instance_of?(NameError)

There are numerous other ways you could check, though the previous methods I outlined are the most commonly used, and typically "preferred" way. Although equality could still be used on the classes, it is typically not the suggested way to achieve it, as it is less flexible, and less clear on the underlying intention, where the above examples indicate exactly how you would like to handle subclasses of the specified error.

ex.class == NameError

I found this answer that explains the subtle differences pretty well.

0
6

I suggest using multiple rescue blocks. First, a specific one that only catches exceptions of type NameError and then a second rescue that catches all error classes:

begin
  c = d
rescue NameError => ex
  puts 'NameError'
rescue => ex
  puts ex.message
end

Not the answer you're looking for? Browse other questions tagged or ask your own question.