InterruptedIOException when using Retrofit2 with rx when retryOn

I am using retrofit 2 with rx-android

I have a pretty complicated retry logic , which partially works . I cut off unnecessary code to simplify it. Here he is:

public class RetryWithDelay implements Func1<Observable<? extends Throwable>, Observable<?>>, Constants { @Override public Observable<?> call(Observable<? extends Throwable> attempts) { return attempts.flatMap(new Func1<Throwable, Observable<?>>() { @Override public Observable<?> call(Throwable throwable) { int statusCode = 500; if (throwable instanceof HttpException) { HttpException httpException = (HttpException) throwable; statusCode = httpException.code(); } boolean shouldRetry = shouldRetry(); if (shouldRetry && statusCode == 401 && requiresAuthorization) { LoginProvider provider = AppUtils.getExternalProvider(context); switch (provider) { case GOOGLE: return reauthorizeGoogleProvider(); case FACEBOOK: return reauthorizeFacebookProvider(); default: return reauthorizeApiProvider(); } } else if (shouldRetry) { return Observable.timer(Configuration.REQUEST_RETRY_DELAY_IN_SECONDS, TimeUnit.SECONDS); } else { return Observable.error(throwable); } } }); } 

I have an observable network call that issues 401. Then the retry logic starts. The call looks like

 observable .subscribeOn(Schedulers.newThread()) .retryWhen(new RetryWithDelay(getActivity())) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<MyArticles>() { //code removed for simplicity }); 

When I get the 401 RetryWithDelay switch, one of three methods starts. It works fine when the user was logically connected to my api, which calls:

 private Observable<?> reauthorizeApiProvider() { return retrofitService.loginWithRefreshToken(data).flatMap(new Func1<User, Observable<?>>() { @Override public Observable<?> call(User user) { app.setUserInfo(UserInfo.fromUser(user)); AppUtils.saveUserData(context, user); return Observable.timer(0, TimeUnit.MICROSECONDS); } }); } 

But for facebook or google, the mysterious exception ends: java.io.InterruptedIOException: thread interrupted . This is how I do it for google - just like for facebook.

 private Observable<?> reauthorizeGoogleProvider() { return retrofitService.loginWithExternalProvider(LoginProvider.GOOGLE, externalAccessToken).flatMap(new Func1<User, Observable<?>>() { @Override public Observable<?> call(User user) { //some irrelevant logic return Observable.timer(0, TimeUnit.MICROSECONDS); } }); } 

There is nothing wrong with the parameters that I pass to the retrofit method. This method with the same parameters is successfully used when signing, and not in terms of repetition logic.

Here is the full stack trace:

  java.io.InterruptedIOException: thread interrupted 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.Timeout.throwIfReached(Timeout.java:145) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.Okio$1.write(Okio.java:77) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.AsyncTimeout$1.write(AsyncTimeout.java:155) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at okio.RealBufferedSink.flush(RealBufferedSink.java:221) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpConnection.flush(HttpConnection.java:141) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpTransport.finishRequest(HttpTransport.java:52) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:904) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.access$300(HttpEngine.java:92) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:891) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:749) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.getResponse(Call.java:268) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:224) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.myapp.android.dagger.ApiModule$1.intercept(ApiModule.java:81) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:221) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:195) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at com.squareup.okhttp.Call.execute(Call.java:79) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.OkHttpCall.execute(OkHttpCall.java:116) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:111) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:88) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:231) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:140) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$3$1.onNext(OnSubscribeRedo.java:307) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$3$1.onNext(OnSubscribeRedo.java:289) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.NotificationLite.accept(NotificationLite.java:150) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.subjects.SubjectSubscriptionManager$SubjectObserver.emitNext(SubjectSubscriptionManager.java:254) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.subjects.BehaviorSubject.onNext(BehaviorSubject.java:160) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OnSubscribeRedo$2$1.onError(OnSubscribeRedo.java:242) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorSubscribeOn$1$1$1.onError(OperatorSubscribeOn.java:71) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.reportError(OperatorMerge.java:239) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.checkTerminate(OperatorMerge.java:774) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:532) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:521) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$InnerSubscriber.onError(OperatorMerge.java:808) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$ThrowObservable$1.call(Observable.java:9600) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$ThrowObservable$1.call(Observable.java:9590) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:231) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMerge$MergeSubscriber.onNext(OperatorMerge.java:140) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:113) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe.call(RxJavaCallAdapterFactory.java:88) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:162) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable$2.call(Observable.java:154) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.Observable.unsafeSubscribe(Observable.java:7710) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.operators.OperatorSubscribeOn$1$1.call(OperatorSubscribeOn.java:62) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 12-20 09:13:48.718 6041-6041/com.myapp.android W/System.err: at java.lang.Thread.run(Thread.java:818) 

Please inform

EDIT: Research shows that this has something to do with the http method. loginWithRefreshToken is POST and loginWithExternalProvider is GET . It works when ti POST changes. But this is stupid. A real solution is required.

+6
source share

All Articles