diff --git a/eo-runtime/src/main/java/org/eolang/PhSafe.java b/eo-runtime/src/main/java/org/eolang/PhSafe.java index c15c363160..86fdb1a097 100644 --- a/eo-runtime/src/main/java/org/eolang/PhSafe.java +++ b/eo-runtime/src/main/java/org/eolang/PhSafe.java @@ -25,6 +25,8 @@ package org.eolang; import EOorg.EOeolang.EOerror; +import java.util.LinkedList; +import java.util.List; /** * An object with coordinates (line and position) and a safe @@ -197,25 +199,52 @@ private T through(final Action action, final String suffix) { this.label(suffix) ); } catch (final Throwable ex) { - final StringBuilder msg = new StringBuilder(0); - final StackTraceElement[] stack = ex.getStackTrace(); - if (stack != null && stack.length > 0) { - final StackTraceElement last = stack[0]; - msg.append(last.getFileName()) - .append(':') - .append(last.getLineNumber()) - .append(": "); - } - msg.append(ex.getClass().getSimpleName()) - .append(": ") - .append(ex.getMessage()); throw new EOerror.ExError( - new Data.ToPhi(msg.toString()), - this.label(suffix) + new Data.ToPhi(ex.getMessage()), + PhSafe.trace(ex, this.label(suffix)) ); } } + /** + * Take stacktrace from exception. + * @param exp The exception + * @param head The head to add + * @return The stacktrace + */ + private static List trace(final Throwable exp, final String head) { + final StackTraceElement[] stack = exp.getStackTrace(); + final List trace = new LinkedList<>(); + if (stack != null) { + for (final StackTraceElement elm : stack) { + trace.add( + String.format( + "%s#%s():%d", + PhSafe.shorter(elm.getClassName()), + elm.getMethodName(), + elm.getLineNumber() + ) + ); + } + } + trace.add( + String.format( + "%s (%s)", + head, PhSafe.shorter(exp.getClass().getName()) + ) + ); + return trace; + } + + /** + * Make class name shorter. + * @param full The full name of class + * @return Shorter name + */ + private static String shorter(final String full) { + return full.replaceAll("(.)[^.]*\\.", "$1."); + } + /** * The label of the exception. * @param suffix The suffix to add to the label diff --git a/eo-runtime/src/test/java/org/eolang/PhSafeTest.java b/eo-runtime/src/test/java/org/eolang/PhSafeTest.java index e8360630c4..e167ef1c4b 100644 --- a/eo-runtime/src/test/java/org/eolang/PhSafeTest.java +++ b/eo-runtime/src/test/java/org/eolang/PhSafeTest.java @@ -62,7 +62,9 @@ public byte[] delta() { ).delta(), "throws correct class" ).messages(), - Matchers.hasItem( + Matchers.hasItems( + Matchers.containsString("o.e.PhSafe#delta()"), + Matchers.containsString("(j.l.IllegalArgumentException)"), Matchers.containsString("Error in \"?.Δ\" at unknown:0:0") ) ); @@ -107,11 +109,7 @@ public Phi take(final String name) { "throws correct class" ).enclosure() ).take(String.class), - Matchers.allOf( - Matchers.startsWith("PhSafeTest.java:"), - Matchers.containsString("IllegalArgumentException"), - Matchers.containsString("intentional error") - ) + Matchers.equalTo("intentional error") ); }