diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java b/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java index e7e6250b4f..c38819e280 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/SignalUncaughtExceptionHandler.java @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.util; import androidx.annotation.NonNull; +import org.signal.core.util.ExceptionUtil; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.keyvalue.SignalStore; @@ -20,7 +21,7 @@ public class SignalUncaughtExceptionHandler implements Thread.UncaughtExceptionH @Override public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { - if (e instanceof OnErrorNotImplementedException) { + if (e instanceof OnErrorNotImplementedException && e.getCause() != null) { e = e.getCause(); } @@ -28,6 +29,6 @@ public class SignalUncaughtExceptionHandler implements Thread.UncaughtExceptionH SignalStore.blockUntilAllWritesFinished(); Log.blockUntilAllWritesFinished(); ApplicationDependencies.getJobManager().flush(); - originalHandler.uncaughtException(t, e); + originalHandler.uncaughtException(t, ExceptionUtil.joinStackTraceAndMessage(e)); } } diff --git a/core-util/src/main/java/org/signal/core/util/ExceptionUtil.java b/core-util/src/main/java/org/signal/core/util/ExceptionUtil.java index 2bdd70721f..65feca52b2 100644 --- a/core-util/src/main/java/org/signal/core/util/ExceptionUtil.java +++ b/core-util/src/main/java/org/signal/core/util/ExceptionUtil.java @@ -2,6 +2,8 @@ package org.signal.core.util; import androidx.annotation.NonNull; +import org.thoughtcrime.securesms.logsubmit.util.Scrubber; + import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -50,6 +52,36 @@ public final class ExceptionUtil { return combinedTrace; } + /** + * Joins the stack trace with the exception's {@link Throwable#getMessage()}. + * + * The resulting stack trace will look like this: + * + * Original + * Stack + * Trace + * [[ ↑↑ Original Trace ↑↑ ]] + * [[ ↓↓ Exception Message ↓↓ ]] + * Exception Message + * + * @return The provided original exception, for convenience. + */ + public static @NonNull E joinStackTraceAndMessage(@NonNull E original) { + StackTraceElement[] originalTrace = original.getStackTrace(); + StackTraceElement[] combinedTrace = new StackTraceElement[originalTrace.length + 3]; + + System.arraycopy(originalTrace, 0, combinedTrace, 0, originalTrace.length); + + CharSequence message = Scrubber.scrub(original.getMessage() != null ? original.getMessage() : "null"); + + combinedTrace[originalTrace.length] = new StackTraceElement("[[ ↑↑ Original Trace ↑↑ ]]", "", "", 0); + combinedTrace[originalTrace.length + 1] = new StackTraceElement("[[ ↓↓ Exception Message ↓↓ ]]", "", "", 0); + combinedTrace[originalTrace.length + 2] = new StackTraceElement(message.toString(), "", "", 0); + + original.setStackTrace(combinedTrace); + return original; + } + public static @NonNull String convertThrowableToString(@NonNull Throwable throwable) { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); throwable.printStackTrace(new PrintStream(outputStream)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java b/core-util/src/main/java/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java similarity index 100% rename from app/src/main/java/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java rename to core-util/src/main/java/org/thoughtcrime/securesms/logsubmit/util/Scrubber.java