Merge pull request #4464 from ByteHamster/swallow-undeliverable-exception
Swallow undeliverable RxJava exceptions
This commit is contained in:
commit
342a082287
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
@ -9,7 +9,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.exception.RxJavaErrorHandlerSetup;
|
||||
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
||||
|
||||
import java.io.File;
|
||||
@ -49,7 +48,6 @@ public class ClientConfig {
|
||||
NetworkUtils.init(context);
|
||||
AntennapodHttpClient.setCacheDirectory(new File(context.getCacheDir(), "okhttp"));
|
||||
SleepTimerPreferences.init(context);
|
||||
RxJavaErrorHandlerSetup.setupRxJavaErrorHandler();
|
||||
NotificationUtils.createChannels(context);
|
||||
initialized = true;
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
package de.danoeh.antennapod.core.util.exception;
|
||||
|
||||
import android.util.Log;
|
||||
import io.reactivex.exceptions.UndeliverableException;
|
||||
import io.reactivex.plugins.RxJavaPlugins;
|
||||
|
||||
public class RxJavaErrorHandlerSetup {
|
||||
|
||||
private RxJavaErrorHandlerSetup() {
|
||||
|
||||
}
|
||||
|
||||
public static void setupRxJavaErrorHandler() {
|
||||
RxJavaPlugins.setErrorHandler(e -> {
|
||||
if (e instanceof UndeliverableException) {
|
||||
// Probably just disposed because the fragment was left
|
||||
Log.d("RxJavaErrorHandler", "Ignored exception: " + Log.getStackTraceString(e));
|
||||
return;
|
||||
}
|
||||
Thread.currentThread().getUncaughtExceptionHandler()
|
||||
.uncaughtException(Thread.currentThread(), e);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package de.danoeh.antennapod.core;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
import com.google.android.gms.common.GoogleApiAvailability;
|
||||
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
|
||||
@ -15,7 +14,6 @@ import de.danoeh.antennapod.core.preferences.UserPreferences;
|
||||
import de.danoeh.antennapod.core.service.download.AntennapodHttpClient;
|
||||
import de.danoeh.antennapod.core.storage.PodDBAdapter;
|
||||
import de.danoeh.antennapod.core.util.NetworkUtils;
|
||||
import de.danoeh.antennapod.core.util.exception.RxJavaErrorHandlerSetup;
|
||||
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
|
||||
|
||||
import java.io.File;
|
||||
@ -67,7 +65,6 @@ public class ClientConfig {
|
||||
}
|
||||
AntennapodHttpClient.setCacheDirectory(new File(context.getCacheDir(), "okhttp"));
|
||||
SleepTimerPreferences.init(context);
|
||||
RxJavaErrorHandlerSetup.setupRxJavaErrorHandler();
|
||||
NotificationUtils.createChannels(context);
|
||||
initialized = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user