Search code examples
rubyerror-handlingrescue

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?


Solution

  • 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]