How to rescue an eval in Ruby?

16,558

Solution 1

Well, that was easy...

It turns out that, by default, the "rescue" statement does not catch all exceptions, but only those that are subclasses of StandardError. SyntaxError is a sibling/cousin of StandardError, not a subclass of it, so the rescue statement doesn't capture it unless explicitly told to.

To have the rescue block capture all exceptions, you need to change the code to the following:

#!/usr/bin/ruby

good_str = "(1+1)"
bad_str = "(1+1"    # syntax error: missing closing paren

begin
    puts eval(good_str)
    puts eval(bad_str)
rescue Exception => exc
    puts "RESCUED!"
end

Note the change in the "rescue" line, from "rescue => exc" to "rescue Exception => exc".

Now, when you run the code, you get the desired results:

2
RESCUED!

Solution 2

Brent already got an answer that works, but I recommend rescuing from the smallest set of exceptions you can get away with. This makes sure you're not accidentally gobbling up something you don't mean to be.

Thus,

begin
  puts eval(good_str)
  puts eval(bad_str)
rescue SyntaxError => se
  puts 'RESCUED!'
end
Share:
16,558
Kym Gilham
Author by

Kym Gilham

Updated on June 07, 2022

Comments

  • Kym Gilham
    Kym Gilham almost 2 years

    I'm trying to figure out how to rescue syntax errors that come up when eval()ing code in Ruby 1.8.6.

    I would expect the following Ruby code:

    #!/usr/bin/ruby
    
    good_str = "(1+1)"
    bad_str = "(1+1"    # syntax error: missing closing paren
    
    begin
        puts eval(good_str)
        puts eval(bad_str)
    rescue => exc
        puts "RESCUED!"
    end
    

    to produce the following result when run:

    2
    RESCUED!
    

    Instead, what I get is:

    2
    eval_rescue.rb:8: (eval):1: compile error (SyntaxError)
    (eval):1: syntax error, unexpected $end, expecting ')'
    

    It appears that the SyntaxError raised by the eval method is being rescued somewhere within the eval, without giving me a chance to handle it myself.

    Anybody have any idea how to get the behavior I want (i.e., for my 'rescue' clause to catch the error from the 'eval')?

  • James Mead
    James Mead about 15 years
    This is good advice. For example, rescuing Exception rather than SyntaxError will prevent you interrupting your process with a ctrl-C.
  • tamouse
    tamouse over 11 years
    I am surprised this has not caught on more as a best practice.
  • gamov
    gamov over 9 years