diff --git a/lib/timeout.rb b/lib/timeout.rb index 11db4be..e7b11c0 100644 --- a/lib/timeout.rb +++ b/lib/timeout.rb @@ -32,6 +32,7 @@ class Error < RuntimeError def self.catch(*args) exc = new(*args) exc.instance_variable_set(:@thread, Thread.current) + exc.instance_variable_set(:@catch_value, exc) ::Kernel.catch(exc) {yield exc} end @@ -40,11 +41,11 @@ def exception(*) if self.thread == Thread.current bt = caller begin - throw(self, bt) + throw(@catch_value, bt) rescue UncaughtThrowError end end - self + super end end @@ -84,7 +85,7 @@ def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ message ||= "execution expired".freeze - if (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) + if Fiber.respond_to?(:current_scheduler) && (scheduler = Fiber.current_scheduler)&.respond_to?(:timeout_after) return scheduler.timeout_after(sec, klass || Error, message, &block) end @@ -115,6 +116,7 @@ def timeout(sec, klass = nil, message = nil, &block) #:yield: +sec+ begin bl.call(klass) rescue klass => e + message = e.message bt = e.backtrace end else diff --git a/test/test_timeout.rb b/test/test_timeout.rb index c57d90c..71607ed 100644 --- a/test/test_timeout.rb +++ b/test/test_timeout.rb @@ -80,6 +80,14 @@ def test_exit_exception end end + def test_raise_with_message + bug17812 = '[ruby-core:103502] [Bug #17812]: Timeout::Error doesn\'t let two-argument raise() set a new message' + exc = Timeout::Error.new('foo') + assert_raise_with_message(Timeout::Error, 'bar', bug17812) do + raise exc, 'bar' + end + end + def test_enumerator_next bug9380 = '[ruby-dev:47872] [Bug #9380]: timeout in Enumerator#next' e = (o=Object.new).to_enum