0

I'm currently using Retrofit 2.3 and RxAndroid for Android as my network communications. Its working fine most of the time. But sometimes, I get a SocketTimeOut exception (I'm assuming due to issues with the internet). I want to be able to handle this case but, putting a try catch around my retrofit calls in my activity doesn't catch this. Likewise, it doesn't go to the OnError method either (I don't see an option for an OnFailure method). The exception, instead, is shown in my RetrofitHelper class, at the return statement of the intercept method. Here is my Retrofit helper class:

public class RetrofitHelper {

/**
 * The APICalls communicates with the json api of the API provider.
 */
public APICalls getAPICalls() {
    final Retrofit retrofit = createRetrofit();
    return retrofit.create(APICalls.class);
}



/**
 * This custom client will append the "username=demo" query after every request.
 */
private OkHttpClient createOkHttpClient() {
    final OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {

            final Request original = chain.request();
            final HttpUrl originalHttpUrl = original.url();

            final HttpUrl url = originalHttpUrl.newBuilder()
                    .build();

            // Request customization: add request headers
            final Request.Builder requestBuilder = original.newBuilder()
                    .url(url);

            final Request request = requestBuilder.build();
            return chain.proceed(request);
        }
    });

    return httpClient.build();
}


/**
 * Creates a pre configured Retrofit instance
 */
private Retrofit createRetrofit() {
    return new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())  // Library for parsing json responses
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // Library for easier threading/background processing
            .client(createOkHttpClient())
            .build();
}

}

And here is my interface for my API calls

public interface APICalls {


    @GET("Vehicle/VehiclePositions.json")
    Single<ResponseVehiclePosition> getVehiclePositions();

    @GET("TripUpdate/TripUpdates.json")
    Single<ResponseTripUpdate> getTripUpdates();

}

And here is the log:

2020-06-05 15:43:34.877 10007-10007/com.samramakrishnan.campusbustracker E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.samramakrishnan.campusbustracker, PID: 10007
    java.net.SocketTimeoutException: failed to connect to transitdata.cityofmadison.com/204.147.0.120 (port 80) from /10.0.2.16 (port 35902) after 10000ms
        at libcore.io.IoBridge.connectErrno(IoBridge.java:191)
        at libcore.io.IoBridge.connect(IoBridge.java:135)
        at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:142)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:390)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:230)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:212)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:436)
        at java.net.Socket.connect(Socket.java:621)
        at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:63)
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:223)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:149)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:192)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:121)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:100)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:120)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at com.samramakrishnan.campusbustracker.restapi.RetrofitHelper$1.intercept(RetrofitHelper.java:55)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:185)
        at okhttp3.RealCall.execute(RealCall.java:69)
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:41)
        at io.reactivex.Observable.subscribe(Observable.java:10179)
        at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
        at io.reactivex.Observable.subscribe(Observable.java:10179)
        at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
        at io.reactivex.Single.subscribe(Single.java:2558)
        at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
        at io.reactivex.Scheduler$1.run(Scheduler.java:134)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:59)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:51)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
shady2020
  • 115
  • 3
  • 13

1 Answers1

0

I think you are able to catch the exception by the BiConsumer in the subscribe method when you call do the GET call.

According to the source file:

public final Disposable subscribe(final Consumer<? super T> onSuccess, final Consumer<? super Throwable> onError)

so I think you can do something like:

compositeDisopsable.add(getAPICalls().getVehiclePositions()
            .subscribeOn(...)
            ...
            .subscribe( response -> {
                //do what you want to do with the `response`
             }, throwable -> {
                if(throwable instanceOf SocketTimeoutException){
                    //handle your exception
             });
ter
  • 16
  • 1