Подтвердить что ты не робот

Ошибка в работе с ошибкой при обновлении

При использовании Observables with Retrofit, как вы справляетесь с сетевым сбоем?

С учетом этого кода:

Observable<GetJobResponse> observable = api.getApiService().getMyData();
observable
    .doOnNext(new Action1<GetJobResponse>() {
        @Override
        public void call(GetJobResponse getJobResponse) {
            //do stuff with my data
        }
    })
    .doOnError(new Action1<Throwable>() {
        @Override
        public void call(Throwable throwable) {
            //do stuff with error message
        }
    });

Запрос просто проваливается без сети, а onError не вызывается. Он не падает, но терпит неудачу. Журналы показывают, что дооснащение получило ошибку:

 java.net.UnknownHostException: Unable to resolve host "api-staging.sittercity.com": No address associated with hostname
     at java.net.InetAddress.lookupHostByName(InetAddress.java:424)
     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
     at java.net.InetAddress.getAllByName(InetAddress.java:214)
     at com.squareup.okhttp.internal.Dns$1.getAllByName(Dns.java:29)

Используя обратные вызовы, это просто передается в onFailure (RetrofitError error). Как я могу получить это с помощью RxJava?

4b9b3361

Ответ 1

Моя проблема была на самом деле в другом месте моего кода. Обработка сетевых ошибок с помощью rxJava + Retrofit очень проста, поскольку он просто бросает RetrofitError в метод onError:

 @Override
 public void onError(Throwable e) {
     if (e instanceof RetrofitError) {
        if (((RetrofitError) e).isNetworkError()) {
            //handle network error
        } else {
            //handle error message from server
        }
     }
 }

Ответ 2

Это чисто проблема с RxJava, не связанная с Retrofit. doOnError является побочным эффектом, поэтому, несмотря на то, что он обрабатывает ошибку, он не "улавливается" в смысле предотвращения его переполнения вперед.

Вы должны посмотреть Операторы обработки ошибок. Самый простой вариант - onErrorReturn(), который позволяет заменить ошибку элементом (экземпляр GetJobResponse).

Вы можете поместить на этот элемент флаг "ошибка", чтобы позже идентифицировать его при подписке на observable. Также важно знать, что если вы не подписываетесь на это наблюдаемое, оно по существу "мертво". Вы всегда должны подписываться на наблюдаемые, а не на использование doOn___, которые являются только побочными эффектами (должны использоваться для ведения журнала и других некритических функциональных возможностей).

Ответ 3

Обратите внимание, что если вы позволяете наблюдаемому emit onError, все восходящие наблюдаемые будут закрыты - независимо от того, "вы поймаете" его с помощью onErrorReturn или onErrorResumeNext. Часто вы этого не хотите. Например, если ваш поток начинается с нажатия кнопки, который запускает запрос на модификацию, который не выполняется, тогда щелчки на кнопках больше не будут распознаваться после прекращения потока.

Используйте Observable<Response<Type>> или Observable<Result<Type>>, чтобы также обрабатывать ошибки в onNext().

с. http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/

Ответ 4

По сравнению с Retrofit2 и RxJava2 исключение RetrofitError не существует. И его преемник HttpException представляет только HTTP-коды ответа на ошибки. Ошибки сети следует обрабатывать с помощью IOException.

 @Override
 public void onError(Throwable e) {
     if (e instanceof IOException) {
            //handle network error
     } else if (e instanceof HttpException) {
            //handle HTTP error response code
     } else {
            //handle other exceptions
     } 
 }