Question about begin, rescue, end.

H

Harold Hausman

Here's my code. It's dumb:

require 'open-uri'
begin
=09while true do
=09=09the_begin_time =3D Time.now
=09=09open( "http://danceliquid.com/test/public/" ) do |stuff|
=09=09=09puts stuff.read
=09=09end
=09=09the_wait_time =3D Time.now - the_begin_time
=09=09the_file =3D File.new("SitePingLog.txt", "a")
=09=09the_file.puts('Got it in '+ the_wait_time.to_s + ' seconds @ ' +
Time.now.to_s)
=09=09the_file.close
=09=09sleep 600
=09end
rescue
=09=09the_file =3D File.new("SitePingLog.txt", "a")
=09=09the_file.puts(Error @ ' + Time.now.to_s)
=09=09the_file.close
=09=09retry
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 (Timeo=
ut::E
rror)
from c:/ruby/lib/ruby/1.8/net/protocol.rb:196:in `timeout'
from c:/ruby/lib/ruby/1.8/timeout.rb:55:in `timeout'
from c:/ruby/lib/ruby/1.8/net/protocol.rb:196:in `rbuf_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:in `readline'
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:in `read_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:in `open_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:in `open'
from C:/Documents and Settings/Harold/Desktop/scripting/ruby/SitePi=
nger.
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
 
G

Gregory Brown

... 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.
 
Z

zdennis

Harold said:
.... 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
 
G

Gregory Brown

'rescue' by itself catches StandardError exceptions and subclasses of Sta= ndardError. The
Timeout::Error is probably not a StandardError, but probably a subclass o=
f Exception.

Yup, that's what it is:
irb(main):004:0> Timeout::Error.ancestors
=3D> [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 ;) )
 
H

Harold Hausman

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. ;) 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.

'rescue' by itself catches StandardError exceptions and subclasses of S= tandardError. 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
=3D> [Timeout::Error, Interrupt, SignalException, Exception, Object, Kern= el]

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

Logan Capaldo

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.
 
G

Gregory Brown

-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?
 
R

Robert Klemme

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
 
S

Stefan Kaes

Robert said:
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
I'd prefer

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

;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top