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