YoYoYo I'm Awesome YoYoYo I'm Awesome - 3 months ago 10
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

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]