Sometimes our Ruby programs throw errors which we don’t have full control over,
such as network timeouts. So, we need to catch and handle those errors. To do
so, we need to choose an
Exception-descended class (or classes) to catch.
What’s the right granularity of that class?
Exception class hierarchy starts with
Exception. If we try to
raise an object that is not an
Exception, Ruby complains.
begin raise 1234.0 rescue => error puts error.inspect end
#<TypeError: exception class/object expected>
rescue only catches things that are
something that isn’t a
StandardError, we have to specify:
begin raise Exception.new rescue Exception => error puts "Correct!" end
We don’t want to rescue
Exceptions, however. Exceptions that aren’t
StandardErrors are reserved for things like
Interrupt when we hit Ctrl-C,
Exceptions that are
StandardErrors are what a normal Ruby program are supposed
In the best-case scenario, we know exactly which error (or errors) can occur.
So, we restrict our
rescue statement to only the subset of errors that are out
of our control:
HTTP_ERRORS = [ EOFError, Errno::ECONNRESET, Errno::EINVAL, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Timeout::Error ] begin some.http.call rescue *HTTP_ERRORS => error notify_airbrake(error) end
By isolating our
rescue statement to a subset of classes, we won’t be
overly-greedy and silently fail when something else goes wrong, such as
On occasion, that won’t be possible. In those cases, we explicitly use
begin some.unique.situation rescue StandardError => error notify_airbrake(error) end
If you found this useful, you might also enjoy: