From: Ye Dingding Date: 2007-08-13T23:05:56+09:00 Subject: Re: Timeout::Error - catchable? ------=_Part_32590_12936113.1187013956386 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline You should handle the exception clearly, that is, rescue TimeoutError. The default action of rescue is to catch the exception which is a subclass of StandardError, but unfortunately, TimeoutError is not. On 8/13/07, Rik Hemsley wrote: > > Hi, > > I'm having trouble catching the exception raised by Timeout.timeout > > Using the following code: > > require 'timeout' > begin > Timeout::timeout(1) do > sleep(5) > end > rescue > puts "rescued in outer" > end > > The interpreter stops with the following: > > /usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error) > from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout' > from test.rb:21 > > I can't catch the exception from within the block, either: > > require 'timeout' > Timeout::timeout(1) do > begin > sleep(5) > rescue > puts "rescued in inner" > end > end > > This gives the same error: > > /usr/lib/ruby/1.8/timeout.rb:54: execution expired (Timeout::Error) > from /usr/lib/ruby/1.8/timeout.rb:56:in `timeout' > from test2.rb:8 > > Is this a known problem, or am I using Timeout incorrectly? > > I am using a workaround for now -- my own implementation: > > module TimeLimit > > class Expired < RuntimeError; end > > def self.timeout(sec, &block) > worker = Thread.new(&block) > killer = Thread.new { sleep sec; worker.raise Expired.new if > worker.alive? } > worker.join > killer.kill if killer.alive? > end > > end > > With the above code, the following prints 'expired' followed by > 'finished', as I would expect: > > TimeLimit::timeout(1) do > begin > sleep 5 > puts "finished" > rescue TimeLimit::Expired > puts "expired" > end > end > > TimeLimit::timeout(5) do > begin > sleep 1 > puts "finished" > rescue TimeLimit::Expired > puts "expired" > end > end > > Cheers, > Rik > > > ------=_Part_32590_12936113.1187013956386--