the example works both on Debian, Ruby 1.8.4 and Gentoo, Ruby 1.8.5
irb(main):006:0> require ‘open-uri’
=> true
irb(main):007:0> begin
irb(main):008:1* open(‘http://www.url.with.timeout.problem.com).read
irb(main):009:1> rescue
irb(main):010:1> puts ‘timeout’
irb(main):011:1> end
/usr/lib/ruby/1.8/timeout.rb:54:in rbuf_fill': execution expired (Timeout::Error) from /usr/lib/ruby/1.8/timeout.rb:56:in timeout’
from /usr/lib/ruby/1.8/timeout.rb:76:in timeout' from /usr/lib/ruby/1.8/net/protocol.rb:132:in rbuf_fill’
from /usr/lib/ruby/1.8/net/protocol.rb:116:in readuntil' from /usr/lib/ruby/1.8/net/protocol.rb:126:in readline’
from /usr/lib/ruby/1.8/net/http.rb:2224:in read_chunked' from /usr/lib/ruby/1.8/net/http.rb:2204:in read_body_0’
from /usr/lib/ruby/1.8/net/http.rb:2170:in read_body' ... 13 levels... from /usr/lib/ruby/1.8/open-uri.rb:30:in open’
from (irb):8:in irb_binding' from /usr/lib/ruby/1.8/irb/workspace.rb:52:in irb_binding’
from /usr/lib/ruby/1.8/irb/workspace.rb:52
I think it’s terrible bad. Rescue without explicit error type should
have deal with every error. Its purpose is to handle unexpected
errors. My production application stopped working by a bad url, but the
whole process was inside a begin-rescue-end block.
This is not the first time. I have seen same when I was dealing with
SCGI source code.
Correct me if I am wrong but I think this is a serious issue in Ruby’s
error handling and should be fixed soon.
I googled for string “rescue exception”, and I found this: “‘rescue’ by
itself is like ‘rescue StandardError’, I believe (which catches
StandardError and all its subclasses)”.
If it works that way, I think, it should be documented in the Ruby book,
exception part.
There is a timeout package in the standard library which will raise an
exception. You could use it in your code like this :
require “timeout”
require “open-uri”
begin
Timeout::timeout(60) do |timeout_length|
open('http://www.url.with.timeout.problem.com).read
end
rescue Timeout::Error
puts “timeout : 60 seconds”
end
The match is made using $!.kind_of?(parameter), and so will succeed if
the parameter has the same class as the exception or is an ancestor of
the exception. If you write a rescue clause with no parameter list,
the
parameter defaults to StandardError.
Easy to miss, though. Took me a while to find it. The explanation is
clearer (IIRC) in the second edition.