Question about begin, rescue, end


#1

Here’s my code. It’s dumb:

require ‘open-uri’
begin
while true do
the_begin_time = Time.now
open( “http://danceliquid.com/test/public/” ) do |stuff|
puts stuff.read
end
the_wait_time = Time.now - the_begin_time
the_file = File.new(“SitePingLog.txt”, “a”)
the_file.puts('Got it in '+ the_wait_time.to_s + ’ seconds @ ’ +
Time.now.to_s)
the_file.close
sleep 600
end
rescue
the_file = File.new(“SitePingLog.txt”, “a”)
the_file.puts(Error @ ’ + Time.now.to_s)
the_file.close
retry
end

#What it does it hit my site every ten minutes, and keep a log of how
long it took to get the content there. I was having people tell me
that intermittently they wouldn’t be able to get to it at all, or
sometimes it would be really slow. This script has proven this to be
true, and in all honesty I’m not too worried about the performance of
my site. My question is, all the open-uri code is inside the begin,
rescue section, and occasionally the rescue, end section gets called,
but also sometimes (infrequently), the whole script bombs out…
here’s the error:

c:/ruby/lib/ruby/1.8/timeout.rb:42:in rbuf_fill': execution expired (Timeout::E rror) from c:/ruby/lib/ruby/1.8/net/protocol.rb:196:intimeout’
from c:/ruby/lib/ruby/1.8/timeout.rb:55:in timeout' from c:/ruby/lib/ruby/1.8/net/protocol.rb:196:inrbuf_fill’
from c:/ruby/lib/ruby/1.8/net/protocol.rb:160:in readuntil' from c:/ruby/lib/ruby/1.8/net/protocol.rb:171:inreadline’
from c:/ruby/lib/ruby/1.8/net/http.rb:1554:in read_status_line' from c:/ruby/lib/ruby/1.8/net/http.rb:1538:inread_new’
from c:/ruby/lib/ruby/1.8/net/http.rb:833:in request' ... 9 levels... from c:/ruby/lib/ruby/1.8/open-uri.rb:134:inopen_uri’
from c:/ruby/lib/ruby/1.8/open-uri.rb:424:in open' from c:/ruby/lib/ruby/1.8/open-uri.rb:85:inopen’
from C:/Documents and
Settings/Harold/Desktop/scripting/ruby/SitePinger.
rb:5

… Right, so, isin’t begin, rescue, end supposed to stop exactly this
from happening? Or chances are, I’ve misunderstood.

Thanks in advance for your time,
-Harold


#2

On 11/17/05, Harold H. removed_email_address@domain.invalid wrote:

… Right, so, isin’t begin, rescue, end supposed to stop exactly this
from happening? Or chances are, I’ve misunderstood.

Thanks in advance for your time,

I think it’s the ‘retry’ that’s causing the error.

This is being called inside of the rescue, which in turn has no rescue.

maybe call exit; at the end of your successful case, and then move
retry outside of the rescue, effectively creating a loop.


#3

Harold H. wrote:

… Right, so, isin’t begin, rescue, end supposed to stop exactly this
from happening? Or chances are, I’ve misunderstood.

‘rescue’ by itself catches StandardError exceptions and subclasses of
StandardError. The
Timeout::Error is probably not a StandardError, but probably a subclass
of Exception. You can will
want to specfically catch Timeout::Error or Exception …

begin

rescue Timeout::Error => ex # or rescue Exception => ex

end

HTH,

Zach


#4

On 11/17/05, zdennis removed_email_address@domain.invalid wrote:

Harold H. wrote:

… Right, so, isin’t begin, rescue, end supposed to stop exactly this
from happening? Or chances are, I’ve misunderstood.

‘rescue’ by itself catches StandardError exceptions and subclasses of StandardError. The
Timeout::Error is probably not a StandardError, but probably a subclass of Exception.

Yup, that’s what it is:
irb(main):004:0> Timeout::Error.ancestors
=> [Timeout::Error, Interrupt, SignalException, Exception, Object,
Kernel]

Ignore my first post and catch one of the above explicitly, and that
should solve your problem
(excluding Object and Kernel, of course :wink: )


#5

On Nov 17, 2005, at 11:42 PM, Harold H. wrote:

Very interesting.

I’d have guessed no arguments would catch anything,

If you really want to catch everything:

begin

rescue Object => ex

end

Of course thats a little extreme.


#6

Very interesting.

I’d have guessed no arguments would catch anything, also strange how 2
functions in the same library (open-uri) would have different
exeception types. 500 errors return something that happens to be
caught as a StandardError while this Timeout::Error is of a whole
different lineage. Oh well, I’m going with it. :wink: We have to operate,
at least currently, under the assumption that the person who wrote the
library is hell of smarter than I am.

I trust that this will fix the problem, though I wont really ever know
for sure because the script only crashed out in that manner every few
days anyway.

Thanks again for all you guys’ help. Long live Ruby.

-Harold
p.s. Are my initial questions getting double posted? or is gmail just
getting confused? 1000 apologies if they are getting double posted.


#7

-Harold
p.s. Are my initial questions getting double posted? or is gmail just
getting confused? 1000 apologies if they are getting double posted.

No. that’s just gmail. Annoying, isn’t it?


#8

Logan C. wrote:

If you really want to catch everything:

begin

rescue Object => ex

rescue Exception => ex


#9

Robert K. wrote:

File.open(“SitePingLog.txt”, “a”) do |the_file|
the_file.puts('Got it in '+ the_wait_time.to_s + ’ seconds @ ’ +
Time.now.to_s)
end

I’d prefer

File.open(“SitePingLog.txt”, “a”) do |file|
file.puts(“Got it in #{the_wait_time} seconds @ #{Time.now}”)
end

:wink:


#10

A general remark: You can greatly improve reliability of your code by
replacing

the_file = File.new(“SitePingLog.txt”, “a”)
the_file.puts('Got it in '+ the_wait_time.to_s + ’ seconds @ ’ +
Time.now.to_s)
the_file.close

with

File.open(“SitePingLog.txt”, “a”) do |the_file|
the_file.puts('Got it in '+ the_wait_time.to_s + ’ seconds @ ’ +
Time.now.to_s)
end

Kind regards

robert

#11

Quoting Logan C. removed_email_address@domain.invalid:


rescue Object => ex

end

Of course thats a little extreme.

Can you raise a non-Exception-derived class? I don’t think you
can…

-mental