Ruby Language Catching Exceptions with Begin / Rescue Retrying


In a rescue clause, you can use retry to run the begin clause again, presumably after changing the circumstance that caused the error.

def divide(x, y)
    puts "About to divide..."
    return x/y
  rescue ZeroDivisionError
    puts "Don't divide by zero!"
    y = 1
  rescue TypeError
    puts "Division only works on numbers!"
    return nil
  rescue => e
    puts "Don't do that (%s)" % [e.class]
    return nil

If we pass parameters that we know will cause a TypeError, the begin clause is executed (flagged here by printing out "About to divide") and the error is caught as before, and nil is returned:

> divide(10, 'a')
About to divide...
Division only works on numbers!
 => nil

But if we pass parameters that will cause a ZeroDivisionError, the begin clause is executed, the error is caught, the divisor changed from 0 to 1, and then retry causes the begin block to be run again (from the top), now with a different y. The second time around there is no error and the function returns a value.

> divide(10, 0)
About to divide...     # First time, 10 ÷ 0
Don't divide by zero!
About to divide...     # Second time 10 ÷ 1
=> 10