java.util.concurrent.ExecutionException in Volley example causes an exception in Rx java
knezmilos13 opened this issue · comments
Hello,
I've just started learning RxJava and I'm going through your examples (which are great, btw).
I've been using Volley a lot, so I wanted to try out the Volley example, however, I get an exception there from time to time:
07-07 11:03:13.327 935-992/com.morihacky.android.rxjava E/routes: com.android.volley.TimeoutError 07-07 11:03:13.331 935-935/com.morihacky.android.rxjava E/AndroidRuntime: FATAL EXCEPTION: main java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread. at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:114) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:192) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:264) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:207) at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException: 2 exceptions occurred. at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:192) at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:120) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:264) at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:207) at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:107) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: rx.exceptions.CompositeException$CompositeExceptionCausalChain: Chain of Causes for CompositeException In Order Received => at android.util.Log.getStackTraceString(Log.java:314) at android.util.Slog.e(Slog.java:77) at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:72) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:118) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4745) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) at dalvik.system.NativeStart.main(Native Method) Caused by: java.util.concurrent.ExecutionException: com.android.volley.TimeoutError at com.android.volley.toolbox.RequestFuture.doGet(RequestFuture.java:117) at com.android.volley.toolbox.RequestFuture.get(RequestFuture.java:88) at com.morihacky.android.rxjava.volley.VolleyDemoFragment.getRouteData(VolleyDemoFragment.java:133) at com.morihacky.android.rxjava.volley.VolleyDemoFragment.access$000(VolleyDemoFragment.java:39) at com.morihacky.android.rxjava.volley.VolleyDemoFragment$1.call(VolleyDemoFragment.java:83) at com.morihacky.android.rxjava.volley.VolleyDemoFragment$1.call(VolleyDemoFragment.java:79) at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) at rx.Observable.unsafeSubscribe(Observable.java:8452) at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94) at rx.internal.schedulers.CachedThreadScheduler$EventLoopWorker$1.call(CachedThreadScheduler.java:222) at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) at java.util.concurrent.FutureTask.run(FutureTask.java:137) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:150) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:264) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) at java.lang.Thread.run(Thread.java:856) Caused by: com.android.volley.TimeoutError at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:147) at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:114)
The cause seems to be a timeout error in Volley; the site which is called (http://www.weather.com.cn/adat/sk/101010100.html) seems to be slow to respond on occasion. I've even had a request executing for 10+ seconds (and Volley default timeout is 5 seconds). The timeout error causes ExecutionException which should be caught and handled by the try/catch block in newGetRouteData method, however this causes something called a "CompositeException" which then kills the app.
I would also suggest avoiding TimeoutErrors even if this exception is solved; maybe use another site, something hosted by google or the like, or set a larger timeout. For instance, this should do the trick, before adding req to request queue:
req.setRetryPolicy(new DefaultRetryPolicy( (int) TimeUnit.SECONDS.toMillis(60), 1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
This sets timeout to 60 seconds, with 1 retry in case of a failure. Although just picking a faster site would probably be enough.
P.S. variable priority in getRoutData() is never used
😵. Unfortunately, i'm not a volley user so not exactly sure how it would work. can you shoot up a PR with these suggestions? i'll be happy to add em.
closing this issue out in favor of the incoming PR ;)