joshdholtz / Sentry-Android

[Deprecated] Use official "raven-java" library
https://github.com/getsentry/sentry-java
MIT License
180 stars 48 forks source link

Exception when capturing exception on background thread #4

Closed suda closed 10 years ago

suda commented 10 years ago

When a exception is being caught on thread other than main (i.e. AsyncTask), sentry throws its own exception:

    java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:299)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    at java.lang.Thread.run(Thread.java:856)
    Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:197)
    at android.os.Handler.<init>(Handler.java:111)
    at com.joshdholtz.protocol.lib.ProtocolClient$ProtocolTask.<init>(ProtocolClient.java:503)
    at com.joshdholtz.protocol.lib.ProtocolClient.doPost(ProtocolClient.java:281)
    at com.joshdholtz.sentry.Sentry.captureEvent(Sentry.java:182)
    at com.joshdholtz.sentry.Sentry.captureException(Sentry.java:142)
    at com.joshdholtz.sentry.Sentry.captureException(Sentry.java:136)
    at com.foo.core.activities.SplashActivity$InitTask.doInBackground(SplashActivity.java:52)
    at com.foo.core.activities.SplashActivity$InitTask.doInBackground(SplashActivity.java:42)
    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    at java.util.concurrent.FutureTask.run(FutureTask.java:234)

It seems to be an issue with your Protocol library (handler not initiated with Looper.getMainLooper()).

joshdholtz commented 10 years ago

Ahh, very interesting. Never crossed my mind that an exception could get thrown in a background thread. This is fun. Be back with a fix in 30 minutes.

joshdholtz commented 10 years ago

@suda Sad day, this needs a Context :-/ Are you calling Sentry.catpureEvent() manually? Because I don't think this error should be able to come from a force closed uncaught exception.

suda commented 10 years ago

Yes, it's captured in try ... catch block with Sentry.captureException(e); Can't context be stored in static instance of Sentry class? It is passed to initializer.

joshdholtz commented 10 years ago

I could store the context in the initializer but I would prefer not. Do you have access to the context from where your calling Sentry.captureException?

joshdholtz commented 10 years ago

I did some research (tweeted Jake Wharton) on if its bad to keep the application context and in a single and its not. So I will look into adding that. I have some client work I need to get done before I can do this so I would use this solution for now.

http://stackoverflow.com/questions/11123621/running-code-in-main-thread-from-another-thread

suda commented 10 years ago

I don't have access to context where I capture exception, so only way would be to store it in sentry. Instead of using context to get main looper, is it possible to use Looper.getMainLooper() ? I'll try to hack it until you fix it :)

joshdholtz commented 10 years ago

@suda Made a fix for this if you want to review - https://github.com/joshdholtz/Sentry-Android/pull/9