YoYoYo I'm Awesome YoYoYo I'm Awesome - 1 year ago 62
Ruby Question

Catching a lot of errors and putting all the errors being caught into a constant

Is there a way, within a rescue clause, to put all the errors into an array and call them from there, if the error is in the array?

For example:

FATAL_ERRORS = %w(Mechanize::ResponseCodeError RestClient::ServiceUnavailable OpenSSL::SSL::SSLError RestClient::BadGateway)

begin
# Do some cool stuff
rescue FATAL_ERRORS => e
puts "Exiting #{e}"


What I've tried:

I've tried grabbing the error from the current thread:

FATAL_ERRORS = Thread.current[:errors] ||= %w(Mechanize::ResponseCodeError RestClient::ServiceUnavailable OpenSSL::SSL::SSLError RestClient::BadGateway)

begin
# Do some cool stuff
rescue FATAL_ERRORS => e
puts "Exiting #{e}"


Also I've tried the splat operator:

FATAL_ERRORS = %w(Mechanize::ResponseCodeError RestClient::ServiceUnavailable OpenSSL::SSL::SSLError RestClient::BadGateway)

begin
# Do some cool stuff
rescue *FATAL_ERRORS => e
puts "Exiting #{e}"


Both the splat and the thread produce the following exception:
rescue in <main>': class or module required for rescue clause (TypeError)


How can I successfully rescue multiple errors without putting them all on the rescue line and making it look bad?

Answer Source

splat does work. Problem is in the way you are making FATAL_ERRORS constant. With %w notation, it converts value as string:

 %w(Mechanize::ResponseCodeError)
 => ["Mechanize::ResponseCodeError"] # Note the string value instead of class constant.

Try

FATAL_ERRORS = [Mechanize::ResponseCodeError, RestClient::ServiceUnavailable, OpenSSL::SSL::SSLError, RestClient::BadGateway]