13
\$\begingroup\$

What would be a prettier/faster way to do handling of multiple errors in Ruby? Here is the code I am working with:

begin
 response = session.get url
rescue Patron::HostResolutionError
 puts "Error resolving remote host."
 exit 1
rescue Patron::PartialFileError
 puts "File size mismatch. (Host reported a file size, but the actual file is of different size)"
 exit 1
rescue Patron::TimeoutError
 puts "Operation timed out."
 exit 1
rescue Patron::TooManyRedirects
 puts "Tried redirecting too many times."
 exit 1
rescue Patron::URLFormatError
 puts "Error with the URL format"
 exit 1
rescue Patron::UnsupportedProtocol
 puts "This URL is using a protocol that we cannot handle."
 exit 1
rescue Patron::ConnectionFailed
 puts "Error connecting to host. Check your internet connection."
 exit 1
end
sepp2k
9,0122 gold badges39 silver badges51 bronze badges
asked Apr 23, 2011 at 21:26
\$\endgroup\$

2 Answers 2

15
\$\begingroup\$

Since you're rescuing all 7 subclasses of Patron::Error, it would make sense to directly rescue Patron::Error rather than rescuing them one by one.

You're also duplicating work that has already been done for you, by formulating your own error message for each exception: the exceptions will already contain a useful error message, which even contains more information than yours do (for example if the host could not be resolved, the exception's message will contain the hostname that could not be resolved instead of just saying "Error resolving remote host").

Lastly I would print error messages to stderr, not stdout, as that's where they're supposed to go.

So I would write the code like this:

begin
 response = session.get url
rescue Patron::Error => e
 $stderr.puts e.message
 exit 1
end
answered Apr 24, 2011 at 0:36
\$\endgroup\$
0
1
\$\begingroup\$

Your begin/rescue code does look repetitive, but on the hand it would be easy to extend in the future. If you are certain you will always have this structure (rescue with an error message + exit), you can abstract it, for example:

exceptions = {
 Patron::HostResolutionError => "Error resolving remote host.",
 ...
}
response = catch_exceptions(exceptions, :exit_code => 1) { session.get(url) }

It's usually handy to write this kind of wrappers so the main code keeps clean (on the other hand, if it gets messier and convoluted it's a good sign the abstraction is just not working).

answered Apr 23, 2011 at 22:27
\$\endgroup\$
2
  • \$\begingroup\$ Apparently, catch can only take 0..1 arguments. As I get an error saying so when I try to run this. \$\endgroup\$ Commented Apr 23, 2011 at 23:03
  • \$\begingroup\$ @Mark. Sorry, I didn't mean Ruby's catch, this is a custom method. Call it with a different name: catch_exceptions, for example. \$\endgroup\$ Commented Apr 24, 2011 at 6:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.