fibers/raising_no_parens.rb
tests/_examples/fibers/raising_no_parens.rb in the metorex repository.
# A fiber that has not started, or has run out, takes no exception.
unborn = Fiber.new { true }
begin
unborn.raise
rescue FiberError => error
p error.message
end
dead = Fiber.new { true }
dead.resume
begin
dead.raise
rescue FiberError => error
p error.message
end
# One that handed control on by a transfer raises where it stands.
root = Fiber.current
parked = Fiber.new do
begin
root.transfer
rescue RuntimeError => error
[:rescued, error.message]
end
end
parked.transfer
p parked.raise "into the transfer"
# One part-way through resuming another passes it on to that one, and the
# exception comes back out through both.
low = Fiber.new { root.transfer }
high = Fiber.new { low.resume }
high.transfer
begin
high.raise RuntimeError, "through the resumer"
rescue RuntimeError => error
p error.message
end
p [low.alive?, high.alive?]
# Raised on the fiber that resumed the one running, it is raised at once.
outer = nil
inner = Fiber.new { outer.raise "back up" }
outer = Fiber.new { inner.resume }
begin
outer.resume
rescue RuntimeError => error
p error.message
end
# Another thread cannot raise in a fiber, which stays usable.
waiting = Fiber.new { Fiber.yield; :resumed }
waiting.resume
Thread.new do
begin
waiting.raise
rescue FiberError => error
p error.message
end
end.join
p waiting.resume
Output:
"cannot raise exception on unborn fiber"
"attempt to resume a terminated fiber"
[:rescued, "into the transfer"]
"through the resumer"
[false, false]
"back up"
"fiber called across threads"
:resumed