Ошибка в работе с ошибкой при обновлении
При использовании 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?
Ответы
Ответ 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
}
}