Support cause: in Thread#raise and Fiber#raise. (#13967)

* Add support for `cause:` argument to `Fiber#raise` and `Thread#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>
This commit is contained in:
Samuel Williams 2025-07-24 14:45:43 +12:00 committed by GitHub
parent 2e0a782936
commit 64f508ade8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 450 additions and 74 deletions

View file

@ -78,6 +78,7 @@
#include "internal/class.h"
#include "internal/cont.h"
#include "internal/error.h"
#include "internal/eval.h"
#include "internal/gc.h"
#include "internal/hash.h"
#include "internal/io.h"
@ -2710,18 +2711,11 @@ rb_threadptr_ready(rb_thread_t *th)
static VALUE
rb_threadptr_raise(rb_thread_t *target_th, int argc, VALUE *argv)
{
VALUE exc;
if (rb_threadptr_dead(target_th)) {
return Qnil;
}
if (argc == 0) {
exc = rb_exc_new(rb_eRuntimeError, 0, 0);
}
else {
exc = rb_make_exception(argc, argv);
}
VALUE exception = rb_exception_setup(argc, argv);
/* making an exception object can switch thread,
so we need to check thread deadness again */
@ -2729,9 +2723,9 @@ rb_threadptr_raise(rb_thread_t *target_th, int argc, VALUE *argv)
return Qnil;
}
rb_ec_setup_exception(GET_EC(), exc, Qundef);
rb_threadptr_pending_interrupt_enque(target_th, exc);
rb_threadptr_pending_interrupt_enque(target_th, exception);
rb_threadptr_interrupt(target_th);
return Qnil;
}