StringFormatter: fix exception format

This commit is contained in:
Johannes Frohnmeyer 2023-03-11 17:00:14 +01:00
parent 7440920099
commit 3e143c4a92
Signed by: Johannes
GPG Key ID: E76429612C2929F4

View File

@ -1,7 +1,7 @@
package io.gitlab.jfronny.commons;
import java.io.*;
import java.util.Locale;
import java.util.*;
import java.util.function.Function;
public class StringFormatter {
public static String toString(Object o) {
@ -11,20 +11,47 @@ public class StringFormatter {
else if (d > 1) return String.format(Locale.US, "%.4f", d);
else return String.format(Locale.US, "%s", d);
} else if (o instanceof Throwable t) {
try {
return t.getMessage() + getStackTrace(t);
} catch (IOException e) {
return t.toString();
}
return toString(t, Objects::toString);
} else return o.toString();
}
public static String getStackTrace(Throwable t) throws IOException {
try (ByteArrayOutputStream baot = new ByteArrayOutputStream()) {
try (PrintStream ps = new PrintStream(baot, true)) {
t.printStackTrace(ps);
}
return baot.toString();
public static String toString(Throwable t, Function<Throwable, String> stringify) {
return stringify.apply(t) + "\n" + getStackTrace(t, stringify);
}
public static String getStackTrace(Throwable t) {
return getStackTrace(t, Objects::toString);
}
public static String getStackTrace(Throwable t, Function<Throwable, String> stringify) {
StringBuilder sb = new StringBuilder();
getStackTrace(sb, t, new StackTraceElement[0], "", "", Objects.requireNonNull(stringify), new HashSet<>(), true);
return sb.toString();
}
private static void getStackTrace(StringBuilder sb, Throwable t, StackTraceElement[] enclosingTrace, String caption, String prefix, Function<Throwable, String> stringify, Set<Throwable> dejaVu, boolean skipHeader) {
if (!skipHeader) sb.append(prefix).append(caption);
if (!dejaVu.add(t)) {
sb.append("[CIRCULAR REFERENCE: ").append(stringify.apply(t)).append("]\n");
return;
}
StackTraceElement[] trace = t.getStackTrace();
int m = trace.length - 1;
int n = enclosingTrace.length - 1;
while (m >= 0 && n >= 0 && trace[m].equals(enclosingTrace[n])) {
m--; n--;
}
int framesInCommon = trace.length - 1 - m;
if (!skipHeader) sb.append(stringify.apply(t)).append('\n');
for (int i = 0; i <= m; i++) sb.append(prefix).append("\tat ").append(trace[i]).append('\n');
if (framesInCommon != 0) sb.append(prefix).append("\t... ").append(framesInCommon).append(" more").append('\n');
for (Throwable se : t.getSuppressed()) {
getStackTrace(sb, se, trace, "Suppressed: ", prefix + "\t", stringify, dejaVu, false);
}
Throwable cause = t.getCause();
if (cause != null) getStackTrace(sb, cause, trace, "Caused by: ", prefix, stringify, dejaVu, false);
}
}