@@ -33,6 +33,8 @@ static VALUE rb_eRactorMovedError;
3333static VALUE rb_eRactorClosedError ;
3434static VALUE rb_cRactorMovedObject ;
3535
36+ static ID id_reference_chain ;
37+
3638static void vm_ractor_blocking_cnt_inc (rb_vm_t * vm , rb_ractor_t * r , const char * file , int line );
3739
3840
@@ -1038,13 +1040,37 @@ ractor_moved_missing(int argc, VALUE *argv, VALUE self)
10381040 *
10391041 */
10401042
1043+ /*
1044+ * call-seq:
1045+ * detailed_message(highlight: false, **kwargs) -> string
1046+ *
1047+ * Returns the message string with the reference chain appended.
1048+ */
1049+ static VALUE
1050+ ractor_error_detailed_message (int argc , VALUE * argv , VALUE exc )
1051+ {
1052+ // Call super to get the base detailed_message
1053+ VALUE base_message = rb_call_super_kw (argc , argv , RB_PASS_CALLED_KEYWORDS );
1054+
1055+ VALUE chain = rb_attr_get (exc , id_reference_chain );
1056+ if (NIL_P (chain )) {
1057+ return base_message ;
1058+ }
1059+
1060+ return rb_sprintf ("%" PRIsVALUE "%" PRIsVALUE , base_message , chain );
1061+ }
1062+
10411063void
10421064Init_Ractor (void )
10431065{
10441066 rb_cRactor = rb_define_class ("Ractor" , rb_cObject );
10451067 rb_undef_alloc_func (rb_cRactor );
10461068
1069+ id_reference_chain = rb_intern_const ("reference_chain" );
1070+
10471071 rb_eRactorError = rb_define_class_under (rb_cRactor , "Error" , rb_eRuntimeError );
1072+ rb_define_method (rb_eRactorError , "detailed_message" , ractor_error_detailed_message , -1 );
1073+
10481074 rb_eRactorIsolationError = rb_define_class_under (rb_cRactor , "IsolationError" , rb_eRactorError );
10491075 rb_eRactorRemoteError = rb_define_class_under (rb_cRactor , "RemoteError" , rb_eRactorError );
10501076 rb_eRactorMovedError = rb_define_class_under (rb_cRactor , "MovedError" , rb_eRactorError );
@@ -1630,13 +1656,16 @@ rb_ractor_make_shareable(VALUE obj)
16301656 VALUE exception = Qfalse ;
16311657 if (rb_obj_traverse (obj , make_shareable_check_shareable , null_leave , mark_shareable , & chain , & exception )) {
16321658 if (exception ) {
1633- VALUE id_mesg = rb_intern ("mesg" );
1634- VALUE message = rb_attr_get (exception , id_mesg );
1635- message = rb_sprintf ("%" PRIsVALUE "%" PRIsVALUE , message , chain );
1636- rb_ivar_set (exception , id_mesg , message );
1659+ if (!NIL_P (chain )) {
1660+ rb_ivar_set (exception , id_reference_chain , chain );
1661+ }
16371662 rb_exc_raise (exception );
16381663 }
1639- rb_raise (rb_eRactorError , "can not make shareable object for %+" PRIsVALUE "%" PRIsVALUE , obj , chain );
1664+ exception = rb_exc_new3 (rb_eRactorError , rb_sprintf ("can not make shareable object for %+" PRIsVALUE , obj ));
1665+ if (!NIL_P (chain )) {
1666+ rb_ivar_set (exception , id_reference_chain , chain );
1667+ }
1668+ rb_exc_raise (exception );
16401669 }
16411670 RB_GC_GUARD (chain );
16421671 RB_GC_GUARD (exception );
@@ -1669,6 +1698,23 @@ rb_ractor_ensure_main_ractor(const char *msg)
16691698 }
16701699}
16711700
1701+ NORETURN (void rb_ractor_raise_isolation_error_with_chain (VALUE klass , VALUE chain , const char * fmt , ...));
1702+
1703+ void
1704+ rb_ractor_raise_isolation_error_with_chain (VALUE klass , VALUE chain , const char * fmt , ...)
1705+ {
1706+ va_list args ;
1707+ va_start (args , fmt );
1708+ VALUE message = rb_vsprintf (fmt , args );
1709+ va_end (args );
1710+
1711+ VALUE exception = rb_exc_new_str (klass , message );
1712+ if (!NIL_P (chain )) {
1713+ rb_ivar_set (exception , id_reference_chain , chain );
1714+ }
1715+ rb_exc_raise (exception );
1716+ }
1717+
16721718static enum obj_traverse_iterator_result
16731719shareable_p_enter (VALUE obj , struct obj_traverse_data * data )
16741720{
0 commit comments