Net:HTTP, Timeout:Error and You

A quick GOTCHA for those looking at using Ruby's Net::HTTP library, which left me tangled for over an hour...

If you're confused as to why sometimes your HTTP.request method raises an exception which doesn't get caught in your generic begin/rescue block, you might like to know that the library uses the timeout standard library. This is important, because the Timeout#timeout raises Timeout::Error which DOES NOT does (see below) inherit from Exception class or StandardError. As such, a rescue statement with no arguments will not catch it!!!

To get it to play nicely and catch these errors from Net::HTTP.request, you'll need to use something like:

begin
	http = Net::HTTP.new(host, port)
	#do stuff here to setup http, and your request
	response = http.request(request)
	#more stuff
rescue Timeout::Error
	#handle stuff here
end

Sure caught me out...


Updated 4 November 2007

Rupert Galea sent me an email around May 2007 making a very good point - rescue catches StandardError by default, not Exception, which is why it doesn't catch Timeout::Error. He says:

FYI per http://www.rubycentral.com/book/tut_exceptions.html
"If you write a rescue clause with no parameter list, the parameter defaults to StandardError."

So if you just write
rescue
you are essentially writing
rescue StandardError

So if you want to rescue everything including Timeout::Error you just need to write
rescue Exception

That's quite right, and something that I originally forgot.