Si je comprends bien, RxJava2 values.take(1)
crée un autre observable qui ne contient qu'un élément de l'observable d'origine. Ce qui DOIT PAS émet une exception car elle est filtrée par l'effet de take(1)
comme c'est arrivé en second.
comme dans le suite extrait de code
Observable<Integer> values = Observable.create(o -> {
o.onNext(1);
o.onError(new Exception("Oops"));
});
values.take(1)
.subscribe(
System.out::println,
e -> System.out.println("Error: " + e.getMessage()),
() -> System.out.println("Completed")
);
1
Completed
io.reactivex.exceptions.UndeliverableException: Java.lang.Exception: Oops
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.Java:366)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.Java:83)
at ch02.lambda$main$0(ch02.Java:28)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.Java:40)
at io.reactivex.Observable.subscribe(Observable.Java:10841)
at io.reactivex.internal.operators.observable.ObservableTake.subscribeActual(ObservableTake.Java:30)
at io.reactivex.Observable.subscribe(Observable.Java:10841)
at io.reactivex.Observable.subscribe(Observable.Java:10827)
at io.reactivex.Observable.subscribe(Observable.Java:10787)
at ch02.main(ch02.Java:32)
Caused by: Java.lang.Exception: Oops
... 8 more
Exception in thread "main" io.reactivex.exceptions.UndeliverableException: Java.lang.Exception: Oops
at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.Java:366)
at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.Java:83)
at ch02.lambda$main$0(ch02.Java:28)
at io.reactivex.internal.operators.observable.ObservableCreate.subscribeActual(ObservableCreate.Java:40)
at io.reactivex.Observable.subscribe(Observable.Java:10841)
at io.reactivex.internal.operators.observable.ObservableTake.subscribeActual(ObservableTake.Java:30)
at io.reactivex.Observable.subscribe(Observable.Java:10841)
at io.reactivex.Observable.subscribe(Observable.Java:10827)
at io.reactivex.Observable.subscribe(Observable.Java:10787)
at ch02.main(ch02.Java:32)
Caused by: Java.lang.Exception: Oops
... 8 more
create(...)
est arrêté. Pour être totalement sûr dans ce cas, vous devez utiliser o.isDisposed()
pour voir si l'observable s'est terminé en aval.onError
d'être perdu. Il est soit livré en aval, soit lancé globalement UndeliverableException
si l'observable est déjà terminé. Il appartient au créateur de l'observable de gérer "correctement" le cas où l'observable est terminé et qu'une exception se produit.Observable
) et le consommateur (Subscriber
) sont en désaccord sur la fin du flux. Puisque le producteur survit au consommateur dans ce cas, le problème ne peut être résolu que chez le producteur.@Kiskae dans le commentaire précédent a correctement répondu à la raison pour laquelle une telle exception peut se produire.
Voici le lien vers la documentation officielle sur ce thème: RxJava2-wiki .
Parfois, vous ne pouvez pas modifier ce comportement, il existe donc un moyen de gérer ces UndeliverableException
. Voici un extrait de code expliquant comment éviter les accidents et les problèmes de comportement:
RxJavaPlugins.setErrorHandler(e -> {
if (e instanceof UndeliverableException) {
e = e.getCause();
}
if ((e instanceof IOException) || (e instanceof SocketException)) {
// fine, irrelevant network problem or API that throws on cancellation
return;
}
if (e instanceof InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
return;
}
if ((e instanceof NullPointerException) || (e instanceof IllegalArgumentException)) {
// that's likely a bug in the application
Thread.currentThread().getUncaughtExceptionHandler()
.handleException(Thread.currentThread(), e);
return;
}
if (e instanceof IllegalStateException) {
// that's a bug in RxJava or in a custom operator
Thread.currentThread().getUncaughtExceptionHandler()
.handleException(Thread.currentThread(), e);
return;
}
Log.warning("Undeliverable exception received, not sure what to do", e);
});
Ce code provient du lien ci-dessus.
Note importante. Cette approche définit le gestionnaire d'erreurs global sur RxJava. Par conséquent, si vous pouviez vous débarrasser de ces exceptions, ce serait une meilleure option.