diff --git a/base/src/main/java/de/staropensource/sosengine/base/Engine.java b/base/src/main/java/de/staropensource/sosengine/base/Engine.java index b9f474d..41689f2 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/Engine.java +++ b/base/src/main/java/de/staropensource/sosengine/base/Engine.java @@ -226,7 +226,7 @@ public final class Engine implements SubsystemMainClass { CrashHandler.getCrashContent().put("Engine", crashContentEngine); CrashHandler.getCrashContent().put("Java Virtual Machine", crashContentJvm); CrashHandler.getCrashContent().put("Operating system", crashContentOS); - CrashHandler.getCrashContent().put("Stacktrace", "%stacktrace%"); + CrashHandler.getCrashContent().put("Stacktrace", "\n%stacktrace%"); } /** diff --git a/base/src/main/java/de/staropensource/sosengine/base/internal/placeholders/crashhandler/Stacktrace.java b/base/src/main/java/de/staropensource/sosengine/base/internal/placeholders/crashhandler/Stacktrace.java index 0a3a528..1e1ef1a 100644 --- a/base/src/main/java/de/staropensource/sosengine/base/internal/placeholders/crashhandler/Stacktrace.java +++ b/base/src/main/java/de/staropensource/sosengine/base/internal/placeholders/crashhandler/Stacktrace.java @@ -20,10 +20,13 @@ package de.staropensource.sosengine.base.internal.placeholders.crashhandler; import de.staropensource.sosengine.base.classes.Placeholder; +import de.staropensource.sosengine.base.exceptions.UnexpectedThrowableException; import de.staropensource.sosengine.base.utility.parser.StackTraceParser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.InvocationTargetException; + /** * Implements the {@code stacktrace} placeholder. * @@ -54,13 +57,50 @@ public final class Stacktrace implements Placeholder { @NotNull @Override public String replace(@NotNull String text) { - String replacement = "No stacktrace is available."; + return text.replace("%stacktrace%", throwable == null ? "No stack trace is available." : getFullStackTrace(throwable)); + } - if (throwable != null) { - StackTraceParser stackTraceParser = new StackTraceParser(throwable); - replacement = stackTraceParser.getHeader() + "\n" + stackTraceParser.getStackTrace(); - } + /** + * Returns the full stack trace. + * + * @param throwable throwable get the full stack trace of + * @return full stack trace + * @since v1-alpha2 + */ + @NotNull + private static String getFullStackTrace(@NotNull Throwable throwable) { + return getFullStackTrace(throwable, new StringBuilder()); + } - return text.replace("%stacktrace%", replacement); + /** + * Returns the full stack trace. + * + * @param throwable throwable to operate on + * @param stacktrace stacktrace to append and return + * @return full stack trace + * @since v1-alpha2 + */ + @NotNull + private static String getFullStackTrace(@NotNull Throwable throwable, @NotNull StringBuilder stacktrace) { + // Add newline + if (!stacktrace.isEmpty()) + stacktrace.append("\n"); + + // Append stack trace + StackTraceParser parser = new StackTraceParser(throwable); + + stacktrace + .append(parser.getHeader()) + .append("\n") + .append(parser.getStackTrace()); + + // Handle throwables which contain other throwables + if (throwable instanceof UnexpectedThrowableException unexpectedThrowableException) + getFullStackTrace(unexpectedThrowableException.getThrowable(), stacktrace); + + if (throwable instanceof InvocationTargetException invocationTargetException) + getFullStackTrace(invocationTargetException.getTargetException(), stacktrace); + + return stacktrace.toString(); // Return stack trace } }