Feature #21360
closedInconsistent Support for `Exception#cause` in `Fiber#raise` and `Thread#raise`
Description
The raise method supports setting the cause of an exception using the cause: keyword, but this behavior does not work as expected when calling Fiber#raise or Thread#raise, resulting in a TypeError. This breaks consistency with Kernel#raise and makes it difficult to attach causal chains to exceptions raised from other execution contexts.
The Problem¶
The following code behaves correctly when using Kernel#raise, correctly setting the cause:
cause = RuntimeError.new("cause")
begin
raise RuntimeError, "boom", cause: cause
rescue => error
pp error: error, cause: error.cause
end
Produces:
{error: #<RuntimeError: boom>, cause: #<RuntimeError: cause>}
However, using Fiber.current.raise or Thread.current.raise with the same arguments produces a TypeError:
begin
Fiber.current.raise RuntimeError, "boom", cause: cause
rescue => error
pp error: error, cause: error.cause
end
Results in:
{error: #<TypeError: backtrace must be an Array of String or an Array of Thread::Backtrace::Location>, cause: nil}
This occurs because the third argument is incorrectly interpreted as a backtrace, not as keyword arguments. A similar issue occurs with Thread#raise.
Proposed Solution¶
Update Fiber#raise and Thread#raise to accept and correctly interpret keyword arguments, including cause:, in the same manner as Kernel#raise. This would restore consistency across all raise implementations and allow causal exception chaining regardless of context. In other words, Fiber#raise and Thread#raise would be defined as the same interface as Kernel#raise.
Updated by ioquatix (Samuel Williams) 5 months ago
- Description updated (diff)
Updated by Eregon (Benoit Daloze) 5 months ago
- Related to Feature #21359: Introduce `Exception#cause=` for Post-Initialization Assignment added
Updated by ioquatix (Samuel Williams) 3 months ago
- Status changed from Open to Assigned
- Assignee set to ioquatix (Samuel Williams)
Updated by ioquatix (Samuel Williams) 3 months ago
- Tracker changed from Bug to Feature
- Backport deleted (
3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN)
I'm changing this to a feature as it's net new code.
Updated by Anonymous 3 months ago
- Status changed from Assigned to Closed
Applied in changeset git|64f508ade8c8535b7d3ecdd217886aa52fddd43c.
Support cause: in Thread#raise and Fiber#raise. (#13967)
- Add support for
cause:argument toFiber#raiseandThread#raise.
The implementation behaviour is consistent with Kernel#raise and
Exception#initialize methods, allowing the cause: argument to be
passed to Fiber#raise and Thread#raise. This change ensures that
the cause: argument is handled correctly, providing a more consistent
and expected behavior when raising exceptions in fibers and threads.
[Feature #21360]
- Shared specs for Fiber/Thread/Kernel raise.
Co-authored-by: Samuel Williams samuel.williams@shopify.com