@@ -222,23 +222,36 @@ print_backtrace(const VALUE eclass, const VALUE errat, const VALUE str, int reve
222
222
223
223
VALUE rb_get_message (VALUE exc );
224
224
225
+ static int
226
+ shown_cause_p (VALUE cause , VALUE * shown_causes )
227
+ {
228
+ VALUE shown = * shown_causes ;
229
+ if (!shown ) {
230
+ * shown_causes = shown = rb_obj_hide (rb_ident_hash_new ());
231
+ }
232
+ if (rb_hash_has_key (shown , cause )) return TRUE;
233
+ rb_hash_aset (shown , cause , Qtrue );
234
+ return FALSE;
235
+ }
236
+
225
237
static void
226
- show_cause (VALUE errinfo , VALUE str , VALUE highlight , VALUE reverse )
238
+ show_cause (VALUE errinfo , VALUE str , VALUE highlight , VALUE reverse , VALUE * shown_causes )
227
239
{
228
240
VALUE cause = rb_attr_get (errinfo , id_cause );
229
- if (!NIL_P (cause ) && rb_obj_is_kind_of (cause , rb_eException )) {
241
+ if (!NIL_P (cause ) && rb_obj_is_kind_of (cause , rb_eException ) &&
242
+ !shown_cause_p (cause , shown_causes )) {
230
243
volatile VALUE eclass = CLASS_OF (cause );
231
244
VALUE errat = rb_get_backtrace (cause );
232
245
VALUE emesg = rb_get_message (cause );
233
246
if (reverse ) {
234
- show_cause (cause , str , highlight , reverse );
247
+ show_cause (cause , str , highlight , reverse , shown_causes );
235
248
print_backtrace (eclass , errat , str , TRUE);
236
249
print_errinfo (eclass , errat , emesg , str , highlight != 0 );
237
250
}
238
251
else {
239
252
print_errinfo (eclass , errat , emesg , str , highlight != 0 );
240
253
print_backtrace (eclass , errat , str , FALSE);
241
- show_cause (cause , str , highlight , reverse );
254
+ show_cause (cause , str , highlight , reverse , shown_causes );
242
255
}
243
256
}
244
257
}
247
260
rb_error_write (VALUE errinfo , VALUE emesg , VALUE errat , VALUE str , VALUE highlight , VALUE reverse )
248
261
{
249
262
volatile VALUE eclass ;
263
+ VALUE shown_causes = 0 ;
250
264
251
265
if (NIL_P (errinfo ))
252
266
return ;
@@ -277,14 +291,14 @@ rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE highlig
277
291
len = p - (msg = buff );
278
292
}
279
293
write_warn2 (str , msg , len );
280
- show_cause (errinfo , str , highlight , reverse );
294
+ show_cause (errinfo , str , highlight , reverse , & shown_causes );
281
295
print_backtrace (eclass , errat , str , TRUE);
282
296
print_errinfo (eclass , errat , emesg , str , highlight != 0 );
283
297
}
284
298
else {
285
299
print_errinfo (eclass , errat , emesg , str , highlight != 0 );
286
300
print_backtrace (eclass , errat , str , FALSE);
287
- show_cause (errinfo , str , highlight , reverse );
301
+ show_cause (errinfo , str , highlight , reverse , & shown_causes );
288
302
}
289
303
}
290
304
0 commit comments