package org.commcare.utils;
import android.content.Context;
import android.content.Intent;
import org.commcare.activities.CrashWarningActivity;
import org.commcare.android.logging.ForceCloseLogger;
import org.javarosa.core.util.NoLocalizedTextException;
import java.lang.Thread.UncaughtExceptionHandler;
/**
* Report unrecoverable exception to servers and shows user crash message
* for certain exceptions. If the user is shown the crash message, they
* are not given the option to report a problem.
*
* @author ctsims
*/
public class CommCareExceptionHandler implements UncaughtExceptionHandler {
private final UncaughtExceptionHandler parent;
private final Context ctx;
public static final String WARNING_MESSAGE_KEY = "warning-message";
public CommCareExceptionHandler(UncaughtExceptionHandler parent,
Context ctx) {
this.parent = parent;
this.ctx = ctx.getApplicationContext();
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// Always report to HQ device logs
ForceCloseLogger.reportExceptionInBg(ex);
if (warnUserAndExit(ex)) {
// You must close the crashed thread in order to start a new activity.
System.exit(0);
} else {
// Default error handling, which includes reporting to ACRA
parent.uncaughtException(thread, ex);
}
}
/**
* Launch activity showing user details of the crash if it is something
* they can fix.
*/
private boolean warnUserAndExit(Throwable ex) {
if (causedByLocalizationException(ex)) {
Intent i = new Intent(ctx, CrashWarningActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra(WARNING_MESSAGE_KEY, ex.getMessage());
ctx.startActivity(i);
return true;
}
return false;
}
private static boolean causedByLocalizationException(Throwable ex) {
return ex != null &&
(ex instanceof NoLocalizedTextException || causedByLocalizationException(ex.getCause()));
}
}