2

Using Java (android but this is a java question ) i have created a default exception handler in the application class like this more or less which was taken from some SO thread:

    public class MyApplication extends Application {
@Override
    public void onCreate() {
        super.onCreate();
        AppInitialization();
    }

    private void AppInitialization() {
         defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
         Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
    }

    private UncaughtExceptionHandler defaultUEH;

    // handler listener
    private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            ex.printStackTrace();
            // TODO handle exception here
        }
    };
}

Lets talk about what my goal is. I need to record extra information for crashLytics crash reports. so anytime a exception occurs the hook uncaughtException(Thread thread, Throwable ex) will be called. i assume that will work for crashes and exceptions (not sure).

3 questions on this:

  1. will this affect how crashLytics works since im overrding the default exception handler.

  2. Will this allow the app to continue - i dont want this. i only want to log the exception somewhere else and have it continue as if the defaultexceptionHandler did not exist. Otherwise, QA regression will have a hard time seeing the bugs so we can fix them. If i call defaultUEH.uncaughtException(thread, ex) from within uncaughtException(thread,ex) will it keep looping ?

  3. What thread is associated with setDefaultUncaughtExceptionHandler ? does this work for all threads for example or just main thread ?

So to be clear, i need a way to send additional information on every crashlytics crash/exception. How ?

UPDATE: I see here that someone found a solution but using this method does it make crashlytics report the fatal issues as well ?

Community
  • 1
  • 1
j2emanue
  • 60,549
  • 65
  • 286
  • 456
  • Just wondering - what kind of additional informations do you need ? – maxoumime Feb 15 '17 at 22:04
  • I want to send business logic with the crash. For example, the applications state like (tokens, UUIDs, the current tab there on) things that can make it easier to recreate the issue. – j2emanue Feb 15 '17 at 22:11
  • I see, have you considered using `Crashlytics.log` ? This way you could prepare logs to be sent with the crash, such as the user behavior in the app, the Activities he opened, the tabs he selected... Just a thought – maxoumime Feb 15 '17 at 22:17
  • yes good point but i was trying to do it all in one area of the app instead of polluting the app with Crashlytics.log calls. i thought it would be cleaner to force the exceptions all into one area and do the work there. – j2emanue Feb 15 '17 at 22:18
  • If you are sending the exact same data at multiple points of your code, I can understand it could be polluting, that's true... – maxoumime Feb 15 '17 at 22:21

1 Answers1

2

i found a way to do this cleanly and it tests ok. be careful with Crashlytics.log to send logs during a crash report. seems to not work consistently on version Crashlytics 2.3.14.151. I use Crashlytics.setString(key, value) instead. crashlytics.log seems to work fine with crashlytics.logException(..) though.

the other question i had was would it work on asychrnous exceptions. The answer is yes i tested it myself.

so it catches all exceptions from all threads.

The rest of the idea is similar to here. The person is using a decorator pattern over the defaultExceptionHandler to add functionality to the uncaughtException method.

this is how i enhanced it:

   public class DefaultUnCaughtExceptionHandlerDecorator implements UncaughtExceptionHandler {

   private UncaughtExceptionHandler mDefaultUncaughtExceptionHandler; //we will decorate the default handler to add functionality to it

   public DefaultUnCaughtExceptionHandlerDecorator(UncaughtExceptionHandler mDefaultUncaughtExceptionHandler) {
       this.mDefaultUncaughtExceptionHandler = mDefaultUncaughtExceptionHandler;
   }

   @Override
   public void uncaughtException(Thread t, Throwable e) {

       logToCrashLytics(); //add our crashlytics logging and keys here
       //  we have added our crashlytics extra data, now invoke Crashlytics
       mDefaultUncaughtExceptionHandler.uncaughtException(t, e);
   }

   private void logToCrashLytics() {

           Crashlytics.setUserIdentifier(Model.getUserID());//or whatever. this will show directly on crashlytics dashboard a pretty element

       Crashlytics.setString("Some useful Info","user is logged in"); // or whatever you want, such as printing out singleton managers references or model info
     //dont use Crashlytics.Log(..) here. it wont work consistent. 
   }

}

now in your subclass of Application class AFTER crashlytics is installed do this:

Thread.setDefaultUncaughtExceptionHandler(new DefaultUnCaughtExceptionHandlerDecorator(Thread.getDefaultUncaughtExceptionHandler()));
Community
  • 1
  • 1
j2emanue
  • 60,549
  • 65
  • 286
  • 456
  • changed what sequence from what to what @KamleshKarwande? – stonedauwg Nov 15 '19 at 20:23
  • _"the other question i had was would it work on asychrnous exceptions. The answer is yes i tested it myself."_ - How do you test something like this quickly, out of interest? – Chucky Mar 28 '23 at 12:33