3

I have a utility method for timing and logging various queries all over the project. The problem is, when looking at crashlytics now all unrelated crashes are joined together into one crash-instance.

Can I catch all exceptions on the utility method, and throw them after removing that method from the stack?

The environment is Android (Java)

UPDATE:

based on @Dhananjay's answer below, here's my code:

public static Cursor get(...) {
    try {
        // my utility code
    } catch (RuntimeException e) {
        throw cleanException(e);
    }
}

private static RuntimeException cleanException(RuntimeException e) {
    try {
        StackTraceElement[] stackTrace = e.getStackTrace();
        StackTraceElement[] subTrace = new StackTraceElement[stackTrace.length - 1];
        System.arraycopy(stackTrace, 1, subTrace, 0, subTrace.length);
        e.setStackTrace(subTrace);
        return e;
    } catch (Throwable ignored) {
        return e;
    }
}
marmor
  • 27,641
  • 11
  • 107
  • 150

1 Answers1

5

This approach might solve your problem: Set the stacktrace of the exception in the utility logging method to exclude the utility method itself, and then throw the exception, here is a working example, you can modify it to eliminate any StackTraceElement you want to:

package test;

public class TestMain {

    public static void main(String args[]) throws Exception {
        try {
            apiCall();
        } catch(Exception e) {
            e.printStackTrace();
        }

    }

    public static void apiCall() throws Exception {
        logAndThrow();

    }

    public static void logAndThrow() throws Exception {
        Exception e = new Exception();
        StackTraceElement[] cleanedUpStackTrace = new StackTraceElement[e.getStackTrace().length -1];
        // Eliminate this mehod i.e. logAndThrow's stack trace entry (i.e. the first one) in cleanedUpStackTrace
        System.arraycopy(e.getStackTrace(), 1, cleanedUpStackTrace, 0, cleanedUpStackTrace.length);
        for(StackTraceElement ste : cleanedUpStackTrace) {
            System.out.println(ste.getMethodName());
        }

        e.setStackTrace(cleanedUpStackTrace);
        throw e;

    }
}

Here is the output of this program, the logAndThrow method is not present in stack trace now:

apiCall
main
java.lang.Exception
    at test.TestMain.apiCall(TestMain.java:33)
    at test.TestMain.main(TestMain.java:25)
Dhananjay
  • 544
  • 3
  • 7
  • epic success! i didn't know i can setStackTrace... I had to limit myself to RuntimeExceptions only, to avoid adding throw Exception everywhere. I'll post my code based on your answer in the question – marmor Sep 19 '16 at 08:51