suku
suku

Reputation: 10937

How to capture the cause of an exception from a throwable?

I have the following code to track uncaught exceptions using google analytics:

ExceptionReporter myHandler =
            new ExceptionReporter(AnalyticsTrackers.getInstance().get(AnalyticsTrackers.Target.APP),
                    Thread.getDefaultUncaughtExceptionHandler(), this);

    ExceptionParser ep = new ExceptionParser() {
        @Override
        public String getDescription(String s, Throwable throwable) {
            return "UserID:" + userID + " Version:" + versionName + " Exception:" + stringifyStacktrace(null, throwable);
        }
    };

private String stringifyStacktrace (Exception e, Throwable t){
    if(e != null) {
        StringWriter sw = new StringWriter();
        e.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    } else {
        return t.toString() + Arrays.toString(t.getStackTrace());
    }
}

The problem is I am getting only the following:

java.lang.RuntimeException: Unable to start activity ComponentInfo{in.jiyofit.basic_app/in.jiyofit.basic_app.WorkoutActivity}: java.lang.ArithmeticException: divide by zero
                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450)
                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510)
                                                                    at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363)
                                                                    at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                    at android.os.Looper.loop(Looper.java:148)
                                                                    at android.app.ActivityThread.main(ActivityThread.java:5461)
                                                                    at java.lang.reflect.Method.invoke(Native Method)
                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

I want the rest of the stacktrace that gives the line cause for the exception. I am not getting the following part of the stacktrace:

Caused by: java.lang.ArithmeticException: divide by zero
                                                                    at in.jiyofit.basic_app.WorkoutActivity.onCreate(WorkoutActivity.java:79)
                                                                    at android.app.Activity.performCreate(Activity.java:6251)
                                                                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)
                                                                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403)
                                                                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510) 
                                                                    at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) 
                                                                    at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                    at android.os.Looper.loop(Looper.java:148) 
                                                                    at android.app.ActivityThread.main(ActivityThread.java:5461) 
                                                                    at java.lang.reflect.Method.invoke(Native Method)

How to get this also?

Upvotes: 2

Views: 1553

Answers (2)

Homayoon Ahmadi
Homayoon Ahmadi

Reputation: 2843

The current answer removes some stacktraces and returns something like ... 14 more in every caused by section, so I wrote my own:

fun getStackTrace(throwable: Throwable) = String.format(
    Locale.ENGLISH, "%s: %s\n\t at %s\n%s",
    throwable.javaClass.canonicalName,
    throwable.message ?: "",
    throwable.stackTrace.joinToString(separator = "\n\t at"),
    getCausedByTrace(throwable)
)


fun getCausedByTrace(throwable: Throwable) = buildString {
    var mThrowable = throwable
    
    while (mThrowable.cause != null && mThrowable != mThrowable.cause) {
        mThrowable = mThrowable.cause!!

        val formattedTrace = String.format(
            Locale.ENGLISH, "Caused by: %s: %s\n\t at %s\n",
            mThrowable.javaClass.canonicalName,
            mThrowable.message ?: "",
            mThrowable.stackTrace.joinToString(separator = "\n\t at")
        )

        append(formattedTrace)
    }
}

Upvotes: 0

Dr. Nitpick
Dr. Nitpick

Reputation: 1712

Try out the static method getStackTraceString() from the Log class

Upvotes: 1

Related Questions