Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - how to check for specific exception after rescue?

Tags:

exception

ruby

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
like image 310
some user Avatar asked Aug 03 '18 19:08

some user


People also ask

What happens if in a begin rescue block the rescue code has an error?

The code between “begin” and “rescue” is where a probable exception might occur. If an exception occurs, the rescue block will execute. You should try to be specific about what exception you're rescuing because it's considered a bad practice to capture all exceptions.

How do I rescue a specific error in Ruby?

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. Note: When using raise without specifying an exception class, Ruby will default to RuntimeError .

Does Ruby have try catch?

Ruby Internal try catch (raise and rescue) In case exceptions happen in the begin block it will halt and control will go between rescue and end, and we can return a valid message for the user in case of exceptions. Every time for a rescue statement Ruby checks and compares the exception raised for each parameter.

How does rescue work in Ruby?

For each rescue clause, the raised Ruby exception is compared against each parameter and the match succeeds if the exception in the clause is the same as or a superclass of the thrown exception. If the thrown Ruby exception does not match any of the specified exception types, the else block gets executed.


2 Answers

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.

like image 172
ForeverZer0 Avatar answered Sep 21 '22 12:09

ForeverZer0


I would go with multiple rescue blocks - one that only catches NameError and another that catches all error classes:

begin
  c = d
rescue NameError => ex
  puts 'NameError'
rescue => ex
  puts ex.message
end
like image 45
spickermann Avatar answered Sep 21 '22 12:09

spickermann