Skip to content
This repository has been archived by the owner on Sep 2, 2020. It is now read-only.

Exceptions #79

Closed
alexblack opened this issue Aug 19, 2015 · 6 comments
Closed

Exceptions #79

alexblack opened this issue Aug 19, 2015 · 6 comments
Labels

Comments

@alexblack
Copy link

Hi, do you have any suggestions on how to manage exceptions? I end up getting very short stacktraces that start in Bolts code, and I lose all my context.

What i've started doing is adding ContinueWith calls that look for exceptions, and wrap them.

@grantland
Copy link
Member

Not really, unfortunately. Java doesn't have a built in way to manage stack traces across threads and our last attempt (#11) caused a lot of OOM issues.

As long as you're not thread switching very often, you should at least have a small stack to look at. Not the best answer, but I don't think there's a solution for any Java concurrency library atm.

@alexblack
Copy link
Author

Ok, thanks. Can you elaborate on what you mean by thread switching? Maybe I need to change something here.

Here is an example stack trace:

com.aadhk.billing.c: Error refreshing inventory (querying prices of items). (response: 6:Error) at com.aadhk.woinvoice.util.ca.a(ProGuard:315) at com.aadhk.billing.g.run(ProGuard:719) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:155) at android.app.ActivityThread.main(ActivityThread.java:5696) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)

But my callstack (conceptually) is much longer, eg I called a setup method, it called another method, and another, and then the final method which hit the error. But my stacktrace is missing the earlier steps.

@alexblack
Copy link
Author

Here's me trying to wrap exceptions at each step, seems like I get long stack traces

 java.lang.Exception: java.lang.Exception: com.aadhk.billing.IabException: Error checking for billing v3 support. (response: 3:Billing Unavailable)
            at com.aadhk.woinvoice.util.IabRef$2.then(IabRef.java:51)
            at com.aadhk.woinvoice.util.IabRef$2.then(IabRef.java:47)
            at bolts.Task$14.run(Task.java:796)
            at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
            at bolts.Task.completeAfterTask(Task.java:787)
            at bolts.Task.access$200(Task.java:31)
            at bolts.Task$10.then(Task.java:592)
            at bolts.Task$10.then(Task.java:589)
            at bolts.Task.runContinuations(Task.java:832)
            at bolts.Task.access$600(Task.java:31)
            at bolts.Task$TaskCompletionSource.trySetError(Task.java:903)
            at bolts.Task$TaskCompletionSource.setError(Task.java:930)
            at bolts.Task$14$1.then(Task.java:811)
            at bolts.Task$14$1.then(Task.java:800)
            at bolts.Task$13.run(Task.java:755)
            at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
            at bolts.Task.completeImmediately(Task.java:746)
            at bolts.Task.continueWith(Task.java:545)
            at bolts.Task.continueWith(Task.java:556)
            at bolts.Task$14.run(Task.java:800)
            at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
            at bolts.Task.completeAfterTask(Task.java:787)
            at bolts.Task.access$200(Task.java:31)
            at bolts.Task$10.then(Task.java:592)
            at bolts.Task$10.then(Task.java:589)
            at bolts.Task.runContinuations(Task.java:832)
            at bolts.Task.access$600(Task.java:31)
            at bolts.Task$TaskCompletionSource.trySetError(Task.java:903)
            at bolts.Task$TaskCompletionSource.setError(Task.java:930)
            at com.aadhk.woinvoice.util.Iab$2.onIabSetupFinished(Iab.java:118)
            at com.aadhk.billing.IabHelper$1.onServiceConnected(IabHelper.java:240)
            at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1208)
            at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1225)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: java.lang.Exception: com.aadhk.billing.IabException: Error checking for billing v3 support. (response: 3:Billing Unavailable)
            at com.aadhk.woinvoice.util.Iab$1.then(Iab.java:83)
            at com.aadhk.woinvoice.util.Iab$1.then(Iab.java:79)
            at bolts.Task$14.run(Task.java:796)
            at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
            at bolts.Task.completeAfterTask(Task.java:787)
            at bolts.Task.access$200(Task.java:31)
            at bolts.Task$10.then(Task.java:592)
            at bolts.Task$10.then(Task.java:589)
            at bolts.Task.runContinuations(Task.java:832)
            at bolts.Task.access$600(Task.java:31)
            at bolts.Task$TaskCompletionSource.trySetError(Task.java:903)
            at bolts.Task$TaskCompletionSource.setError(Task.java:930)
            at com.aadhk.woinvoice.util.Iab$2.onIabSetupFinished(Iab.java:118)
            at com.aadhk.billing.IabHelper$1.onServiceConnected(IabHelper.java:240)
            at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1208)
            at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1225)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
     Caused by: com.aadhk.billing.IabException: Error checking for billing v3 support. (response: 3:Billing Unavailable)
            at com.aadhk.woinvoice.util.Iab$2.onIabSetupFinished(Iab.java:118)
            at com.aadhk.billing.IabHelper$1.onServiceConnected(IabHelper.java:240)
            at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1208)
            at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1225)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5254)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

@grantland
Copy link
Member

Ok, thanks. Can you elaborate on what you mean by thread switching? Maybe I need to change something here.

By thread switching I mean when you jump between different executors:

task.continueWithTask((t) -> {
  // ...

  return t.continueWithTask((t) -> {
    // ...
  }, Task.UI_EXECUTOR);
}, Task.BACKGROUND_EXECUTOR);

The code looks inline (ish), but since we're executing on different executors, each continuation will have it's own call stack. You're not doing anything wrong, it's just a nuance of the VM.

Here's me trying to wrap exceptions at each step, seems like I get long stack traces

That's going to happen, but you could trim it if you want. I believe #11 has some of that logic.

@alexblack
Copy link
Author

Thanks, that helps, I will look at using the same executor more consistently!

I am often calling Parse functions, like saveInBackground etc. Should I use the network executor in my code so that if an exception happens saving with Parse then I get a better stack trace? (Assuming that the network executor is what Parse is using here)

@grantland
Copy link
Member

Thread switching isn't bad, it just doesn't give informative stack traces.

As far as I know, starting off on the same executor doesn't guarantee nested or following continuations with the same executor will be inline on the current thread. In addition, there might be a different executor defined for a continuation somewhere down the chain that will jump threads.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants