summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2020-09-29 12:00:40 +0200
committerByteHamster <info@bytehamster.com>2020-09-29 12:23:13 +0200
commitf54076ca587e89c8af1bfb3d4a8e5bb442405e85 (patch)
tree527133895e75124ecd5f9f9eb9c8bc7b115c1aa1 /app
parent6b173d0c1adb36a0475871c13c82d8e6071573ce (diff)
downloadAntennaPod-f54076ca587e89c8af1bfb3d4a8e5bb442405e85.zip
Swallow undeliverable RxJava exceptions
AntennaPod threads might throw NPEs after disposing because we set controllers to null.
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/de/danoeh/antennapod/PodcastApp.java3
-rw-r--r--app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java2
-rw-r--r--app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java (renamed from app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java)11
-rw-r--r--app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java36
-rw-r--r--app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java3
5 files changed, 49 insertions, 6 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
index ed3f4e8f1..534d48479 100644
--- a/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
+++ b/app/src/main/java/de/danoeh/antennapod/PodcastApp.java
@@ -12,6 +12,8 @@ import com.joanzapata.iconify.fonts.MaterialModule;
import de.danoeh.antennapod.activity.SplashActivity;
import de.danoeh.antennapod.core.ApCoreEventBusIndex;
import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.error.CrashReportWriter;
+import de.danoeh.antennapod.error.RxJavaErrorHandlerSetup;
import de.danoeh.antennapod.spa.SPAUtil;
import org.greenrobot.eventbus.EventBus;
@@ -38,6 +40,7 @@ public class PodcastApp extends Application {
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(new CrashReportWriter());
+ RxJavaErrorHandlerSetup.setupRxJavaErrorHandler();
if (BuildConfig.DEBUG) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder()
diff --git a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
index 48264bb26..fde7c0484 100644
--- a/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
+++ b/app/src/main/java/de/danoeh/antennapod/activity/BugReportActivity.java
@@ -7,7 +7,7 @@ import android.os.Bundle;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.TextView;
-import de.danoeh.antennapod.CrashReportWriter;
+import de.danoeh.antennapod.error.CrashReportWriter;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.util.IntentUtils;
diff --git a/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java b/app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java
index b5d0f6945..dc62863f9 100644
--- a/app/src/main/java/de/danoeh/antennapod/CrashReportWriter.java
+++ b/app/src/main/java/de/danoeh/antennapod/error/CrashReportWriter.java
@@ -1,8 +1,9 @@
-package de.danoeh.antennapod;
+package de.danoeh.antennapod.error;
import android.os.Build;
import android.util.Log;
+import de.danoeh.antennapod.BuildConfig;
import org.apache.commons.io.IOUtils;
import java.io.File;
@@ -31,6 +32,11 @@ public class CrashReportWriter implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
+ write(ex);
+ defaultHandler.uncaughtException(thread, ex);
+ }
+
+ public static void write(Throwable exception) {
File path = getFile();
PrintWriter out = null;
try {
@@ -41,14 +47,13 @@ public class CrashReportWriter implements Thread.UncaughtExceptionHandler {
out.println();
out.println("## StackTrace");
out.println("```");
- ex.printStackTrace(out);
+ exception.printStackTrace(out);
out.println("```");
} catch (IOException e) {
Log.e(TAG, Log.getStackTraceString(e));
} finally {
IOUtils.closeQuietly(out);
}
- defaultHandler.uncaughtException(thread, ex);
}
public static String getSystemInfo() {
diff --git a/app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java b/app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java
new file mode 100644
index 000000000..1c7f5f0b4
--- /dev/null
+++ b/app/src/main/java/de/danoeh/antennapod/error/RxJavaErrorHandlerSetup.java
@@ -0,0 +1,36 @@
+package de.danoeh.antennapod.error;
+
+import android.util.Log;
+import de.danoeh.antennapod.BuildConfig;
+import io.reactivex.exceptions.UndeliverableException;
+import io.reactivex.plugins.RxJavaPlugins;
+
+public class RxJavaErrorHandlerSetup {
+ private static final String TAG = "RxJavaErrorHandler";
+
+ private RxJavaErrorHandlerSetup() {
+
+ }
+
+ public static void setupRxJavaErrorHandler() {
+ RxJavaPlugins.setErrorHandler(exception -> {
+ if (exception instanceof UndeliverableException) {
+ // Probably just disposed because the fragment was left
+ Log.d(TAG, "Ignored exception: " + Log.getStackTraceString(exception));
+ return;
+ }
+
+ // Usually, undeliverable exceptions are wrapped in an UndeliverableException.
+ // If an undeliverable exception is a NPE (or some others), wrapping does not happen.
+ // AntennaPod threads might throw NPEs after disposing because we set controllers to null.
+ // Just swallow all exceptions here.
+ Log.e(TAG, Log.getStackTraceString(exception));
+ CrashReportWriter.write(exception);
+
+ if (BuildConfig.DEBUG) {
+ Thread.currentThread().getUncaughtExceptionHandler()
+ .uncaughtException(Thread.currentThread(), exception);
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
index 367593131..7a282fc82 100644
--- a/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
+++ b/app/src/main/java/de/danoeh/antennapod/preferences/PreferenceUpgrader.java
@@ -5,12 +5,11 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import de.danoeh.antennapod.BuildConfig;
-import de.danoeh.antennapod.CrashReportWriter;
+import de.danoeh.antennapod.error.CrashReportWriter;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
-import de.danoeh.antennapod.core.util.gui.NotificationUtils;
public class PreferenceUpgrader {
private static final String PREF_CONFIGURED_VERSION = "version_code";