Модернизация 2.3 Обработка исключения SocketTimeoutException

В настоящее время я использую Retrofit 2.3 и RxAndroid для Android в качестве сетевых коммуникаций. Большую часть времени он работает нормально. Но иногда я получаю исключение SocketTimeOut (я полагаю, из-за проблем с Интернетом). Я хочу иметь возможность справиться с этим случаем, но попытка поймать мои вызовы модификации в моей деятельности не улавливает этого. Точно так же он не переходит к методу OnError (я не вижу варианта для метода OnFailure). Вместо этого исключение отображается в моем классе RetrofitHelper в операторе возврата метода перехвата. Вот мой вспомогательный класс Retrofit:

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();
}

}

А вот мой интерфейс для моих вызовов API

public interface APICalls {


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

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

}

А вот журнал:

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)

person shady2020    schedule 06.06.2020    source источник


Ответы (1)


Я думаю, вы можете поймать исключение BiConsumer в методе subscribe, когда вы вызываете вызов GET.

Согласно исходному файлу:

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

поэтому я думаю, что вы можете сделать что-то вроде:

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