11
11
12
12
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
13
13
import com .oracle .truffle .api .TruffleException ;
14
+ import com .oracle .truffle .api .TruffleStackTrace ;
14
15
import com .oracle .truffle .api .dsl .UnsupportedSpecializationException ;
15
16
import com .oracle .truffle .api .frame .VirtualFrame ;
16
17
import com .oracle .truffle .api .nodes .ControlFlowException ;
19
20
import org .truffleruby .Layouts ;
20
21
import org .truffleruby .language .RubyGuards ;
21
22
import org .truffleruby .language .RubyNode ;
23
+ import org .truffleruby .language .backtrace .Backtrace ;
22
24
import org .truffleruby .language .backtrace .BacktraceFormatter ;
23
25
import org .truffleruby .language .backtrace .BacktraceFormatter .FormattingFlags ;
24
26
import org .truffleruby .language .control .JavaException ;
@@ -261,13 +263,19 @@ private DynamicObject translateThrowable(Throwable throwable) {
261
263
262
264
final StringBuilder builder = new StringBuilder ();
263
265
boolean firstException = true ;
266
+ Backtrace lastBacktrace = null ;
264
267
265
268
while (t != null ) {
266
269
if (t .getClass ().getSimpleName ().equals ("LazyStackTrace" )) {
267
270
// Truffle's lazy stracktrace support, not a real exception
268
271
break ;
269
272
}
270
273
274
+ if (lastBacktrace != null ) {
275
+ appendTruffleStackTrace (builder , lastBacktrace );
276
+ lastBacktrace = null ;
277
+ }
278
+
271
279
if (!firstException ) {
272
280
builder .append ("Caused by:\n " );
273
281
}
@@ -285,13 +293,17 @@ private DynamicObject translateThrowable(Throwable throwable) {
285
293
// Java exception, print it formatted like a Ruby exception
286
294
final String message = t .getMessage ();
287
295
builder .append (message != null ? message : "<no message>" );
288
-
289
296
builder .append (" (" ).append (t .getClass ().getSimpleName ()).append (")\n " );
290
297
291
- // Print the first 10 lines of backtrace
292
- final StackTraceElement [] stackTrace = t .getStackTrace ();
293
- for (int i = 0 ; i < Math .min (stackTrace .length , 10 ); i ++) {
294
- stackTraceElementToRuby (builder , stackTrace [i ]);
298
+ if (t instanceof TruffleException ) {
299
+ lastBacktrace = new Backtrace ((TruffleException ) t );
300
+ } else {
301
+ // Print the first 10 lines of the Java stacktrace
302
+ appendJavaStackTrace (t , builder , 10 );
303
+
304
+ if (TruffleStackTrace .getStackTrace (t ) != null ) {
305
+ lastBacktrace = new Backtrace (t );
306
+ }
295
307
}
296
308
}
297
309
@@ -302,11 +314,24 @@ private DynamicObject translateThrowable(Throwable throwable) {
302
314
// When printing the backtrace of the exception, make it clear it's not a cause
303
315
builder .append ("Translated to internal error" );
304
316
305
- return coreExceptions ().runtimeError (builder .toString (), this , throwable );
317
+ if (lastBacktrace != null ) {
318
+ return coreExceptions ().runtimeError (builder .toString (), lastBacktrace );
319
+ } else {
320
+ return coreExceptions ().runtimeError (builder .toString (), this , throwable );
321
+ }
322
+ }
323
+
324
+ private void appendTruffleStackTrace (StringBuilder builder , Backtrace backtrace ) {
325
+ final BacktraceFormatter formatter = new BacktraceFormatter (getContext (), EnumSet .noneOf (FormattingFlags .class ));
326
+ final String formattedBacktrace = formatter .formatBacktrace (null , backtrace );
327
+ builder .append (formattedBacktrace ).append ('\n' );
306
328
}
307
329
308
- private void stackTraceElementToRuby (StringBuilder builder , StackTraceElement stackTraceElement ) {
309
- builder .append ('\t' ).append ("from " ).append (stackTraceElement ).append ('\n' );
330
+ private void appendJavaStackTrace (Throwable t , StringBuilder builder , int limit ) {
331
+ final StackTraceElement [] stackTrace = t .getStackTrace ();
332
+ for (int i = 0 ; i < Math .min (stackTrace .length , limit ); i ++) {
333
+ builder .append ('\t' ).append ("from " ).append (stackTrace [i ]).append ('\n' );
334
+ }
310
335
}
311
336
312
337
}
0 commit comments