44

Can't figure out why is this happening. Neither one of rx callbacks (onCompleted(), onError(), onNext()) not gets triggered by my call. The only thing i receive is this okhttp output:

D/OkHttp: --> GET https://api.privatbank.ua/p24api/exchange_rates?json=true&date=20.11.2016 http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled

Retrofit module:

@Module
public class RestModule {

    @Provides
    @Singleton
    public HttpLoggingInterceptor providesHttpLogginInterceptor() {
        return new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
    }

    @Provides
    @Singleton
    public OkHttpClient providesOkHttpClient(@NonNull HttpLoggingInterceptor loggingInterceptor) {
        return new OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .connectTimeout(ConstantsManager.CONNECTION_TIME_OUT, TimeUnit.SECONDS)
            .readTimeout(ConstantsManager.READ_TIME_OUT, TimeUnit.SECONDS)
            .build();
    }

    @Provides
    @Singleton
    public Gson providesGson() {
        return new GsonBuilder().create();
    }

    @Provides
    @Singleton
    public Retrofit providesRetrofit(@NonNull OkHttpClient okHttpClient, @NonNull Gson gson) {
        return new Retrofit.Builder()
            .baseUrl(ConstantsManager.BASE_URL)
            .client(okHttpClient)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    }

    @Provides
    @Singleton
    public PrivatbankApi providesPrivatbankApi(@NonNull Retrofit retrofit) {
        return retrofit.create(PrivatbankApi.class);
    }
}

API interface:

public interface PrivatbankApi {

    @GET
    Observable<CurrentRates> loadCurrentRates(@NonNull @Url String url);

    @GET("exchange_rates")
    Observable<DateRates> loadDateRates(@NonNull @Query("json") Boolean json, @NonNull @Query("date") String date);

}

Subscription:

subscription = dataManager.loadDateRates(date)
                .subscribeOn(Schedulers.io())
                .doAfterTerminate(() -> {
                })
                .subscribe(dateRates -> {
                    // My code here...
                }, throwable -> {
                    Timber.e(throwable, "Error while loading data occurred!");
                });

By the way, both of the calls gets the same error:

D/OkHttp: --> GET https://privat24.privatbank.ua/p24/accountorder?oper=prp&PUREXML&apicour&country=ua http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled
D/OkHttp: --> GET https://api.privatbank.ua/p24api/exchange_rates?json=true&date=20.11.2016 http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled
stkent
  • 19,772
  • 14
  • 85
  • 111
oleg.v
  • 1,065
  • 3
  • 11
  • 20

5 Answers5

74

That exception gets thrown if the request is cancelled by the user. When using RxJavaCallAdapterFactory this happens if the subscription is unsubscribed before the call can complete. So I guess at some point after you do the call you do subscription.unsubscribe() which cancels the underlying requests.

Kiskae
  • 24,655
  • 2
  • 77
  • 74
  • 5
    I have the same problem when it moved to disposable and put it in ondestroy class of the intent service class, and calling `disposable.dispose()` – Kiran Benny Joseph Sep 22 '17 at 06:19
  • 2
    Guys, where to do the subscription.unsubscribe() , facing same issue – Harshad07 Jun 07 '18 at 09:14
  • 2
    I call disposable.dispose() in onDestroy but when Im back to that page after exiting, the `OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled` appeared again. Can someone help me out of this issue ? – Lester L. Aug 23 '18 at 11:29
1

What helped to me is to replace deprecated call adapter:

implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

with:

implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'

This helped me with this issue and I get onError() called every time. More info on this: https://github.com/JakeWharton/retrofit2-rxjava2-adapter

Komoi
  • 43
  • 8
1

I had the same problem but in my case when two requests subscribed in the same CompositeDisposable one of them gets cancelled. I mean those 2 requests are done in parallel.

My Solution: I only defined two different subscription channels.

0

Thanks to @Kiskae. This gave me the correct hint. In my case I used a CompositeSubscription and added a subscription to it after it was unsubscribed by another method.

/**
 * Adds a new {@link Subscription} to this {@code CompositeSubscription} if the
 * {@code CompositeSubscription} is not yet unsubscribed. If the {@code CompositeSubscription} <em>is</em>
 * unsubscribed, {@code add} will indicate this by explicitly unsubscribing the new {@code Subscription} as
 * well.
 *
 * @param s
 *         the {@link Subscription} to add
 */
luckyhandler
  • 10,651
  • 3
  • 47
  • 64
  • Hi, where should i put subscription.unsubscribe() , facing the same issue. – Harshad07 Jun 07 '18 at 09:01
  • on the CompositeSubscription which you hold as property / global variable in your class – luckyhandler Jun 07 '18 at 10:32
  • remote.getContactDetails(contactId) .performOnBackOutOnMain(scheduler) .subscribe({ data -> mContactResponse.success(data) },{ error -> mContactResponse.failed(error) }) .addTo(compositeDisposable) I am giving remote call like this. – Harshad07 Jun 07 '18 at 10:34
  • I was actually working with RxJava 1, this seems to be RxJava 2 related. But I guess something unsubscribed from compositeDisposable before you use it – luckyhandler Jun 07 '18 at 10:38
  • i am posting my code in few minutes , please have a look once. – Harshad07 Jun 07 '18 at 10:42
  • Please check this code : https://stackoverflow.com/questions/50739281/http-failed-java-net-socketexception-socket-closed-retrofit?noredirect=1#comment88486176_50739281 – Harshad07 Jun 07 '18 at 10:54
0

Using Kotlin coroutines I got the same exception. First I closed a ViewModel (and a dialog) and then started a Job with HTTP-request. In this case the coroutine was cancelled: kotlinx.coroutines.JobCancellationException: Job was cancelled; job=SupervisorJobImpl{Cancelling}.

close()
modelScope.launch {
    val response = withContext(Dispatchers.IO) {
        ...
    }
    response?.let { ... }
}

Then I moved closing the ViewModel to the end of the request.

CoolMind
  • 26,736
  • 15
  • 188
  • 224