-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
Behavior
Nested timeout blocks can result in a Timeout::ExitException being raised, rather than a Timeout::Error
How to reproduce
The below will sometimes raise a Timeout::ExitException, sometimes a Timeout::Error (roughly 50/50).
begin
Timeout.timeout(2) do
Timeout.timeout(2) do
sleep 3
end
end
rescue Exception => e
puts "raised a #{e.class}"
end
Cause (maybe)
Hacking up the Timeout module as follows:
module Timeout
class Error
def self.handle_timeout(message) # :nodoc:
exc = ExitException.new(message)
begin
puts "yield #{exc.object_id} (#{message})"
yield exc
rescue ExitException => e
puts "test #{e.object_id} vs #{exc.object_id} => #{exc.equal?(e)} (#{message})"
raise new(message) if exc.equal?(e)
puts "re-raise #{e.object_id}('#{e}') (#{message})"
raise
end
end
end
end
Timeout.timeout(2, nil, "outer timeout") do
Timeout.timeout(2, nil, "inner timeout") do
sleep 3
end
end
shows that, when an ExitException is raised, the "inner" exception is being caught by the "outer" handle_timeout block. Suspicious this is the result of indeterminate Thread#raise behavior?
Environment
Ruby 3.3.5
Timeout 0.4.1
Ubuntu 24.04.1 running on WSL2
Metadata
Metadata
Assignees
Labels
No labels