У меня есть такая ситуация, когда я делаю несколько веб-запросов параллельно.Иногда я делаю эти вызовы, и все запросы видят одну и ту же ошибку (например, отсутствие сети):
void main() {
Observable.just("a", "b", "c")
.flatMap(s -> makeNetworkRequest())
.subscribe(
s -> {
// TODO
},
error -> {
// handle error
});
}
Observable<String> makeNetworkRequest() {
return Observable.error(new NoNetworkException());
}
class NoNetworkException extends Exception {
}
В зависимости от времени, если один запрос испускает NoNetworkException
перед остальнымиможет, Retrofit / RxJava удалит / прервет ** другие.Я посмотрю один из следующих журналов (не все три) для каждого оставшегося запроса ++:
<-- HTTP FAILED: java.io.IOException: Canceled
<-- HTTP FAILED: java.io.InterruptedIOException
<-- HTTP FAILED: java.io.InterruptedIOException: thread interrupted
Я смогу обработать ошибку NoNetworkException в подписчике, и все последующие потоки будут удаленыи все в порядке.
Однако, исходя из времени, если два или более веб-запроса испускают NoNetworkException
, то первый вызовет вышеуказанные события, уничтожая все в нисходящем направлении.Второму NoNetworkException
некуда будет идти, и я получу страшный UndeliverableException
.Это то же самое, что описано в примере № 1 здесь .
В приведенной выше статье автор предложил использовать обработчик ошибок.Очевидно, retry
/ retryWhen
не имеет смысла, если я ожидаю услышать те же ошибки снова.Я не понимаю, как onErrorResumeNext
/ onErrorReturn
здесь помогают, если я не сопоставлю их с чем-то, что можно восстановить для последующей обработки:
Observable.just("a", "b", "c")
.flatMap(s ->
makeNetworkRequest()
.onErrorReturn(error -> {
// eat actual error and return something else
return "recoverable error";
}))
.subscribe(
s -> {
if (s.equals("recoverable error")) {
// handle error
} else {
// TODO
}
},
error -> {
// handle error
});
, но это кажется странным.
Я знаюдругое решение - установить глобальный обработчик ошибок с RxJavaPlugins.setErrorHandler()
.Это тоже не кажется хорошим решением.Возможно, я захочу по-разному обрабатывать NoNetworkException
в разных частях моего приложения.
Итак, какие еще варианты у меня есть?Что другие люди делают в этом случае?Это должно быть довольно распространенным явлением.
** Я не до конца понимаю, кто кому мешает.RxJava избавляется от всех других запросов в flatmap, что, в свою очередь, заставляет Retrofit отменять запросы?Или Retrofit отменяет запросы, в результате чего каждый запрос в плоской карте испускает одно из указанных выше исключений IOException?Я думаю, что на самом деле не имеет значения отвечать на вопрос, просто любопытно.
++ Возможно, что не все запросы a, b и c выполняются в зависимости от пула потоков.