web-dev-qa-db-fra.com

RxJava: Comment gérer les erreurs avec l'opérateur Zip?

J'utilise RxJava et RxAndroid avec Retrofit2.

Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());

Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());

En utilisant l'opérateur Zip comme ci-dessous sur deux observateur ci-dessus. 

 Observable<ArrayList<TestData>> testDataObservable = Observable.Zip(responseOneObservable, responseTwoObservable, new Func2<ResponseOne, ResponseTwo, ArrayList<TestData>>() {
            @Override
                public ArrayList<TestData> call(ResponseOne responseOne, ResponseTwo responseTwo) {
                  ArrayList<TestData> testDataList = new ArrayList();
                      // Add test data from response responseOne & responseTwo
                  return testDataList;
            } 
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<ArrayList<TestData>>() {

        @Override
        public void onNext(ArrayList<TestData> testDataList) {

        }

        @Override
        public void onCompleted() {
            Log.d(TAG, "onCompleted" );
        }

        @Override
        public void onError(Throwable t) {
            Log.d(TAG, "onError Throwable: " + t.toString() );
        }
    });

Si une erreur survient lors de la modification de l'appel http dans responseOneObservable et responseTwoObservable, elle appelle directement la méthode onError de l'abonné de testDataObservable.

Je souhaite continuer à utiliser la méthode call de l'opérateur Zip même si une personne sur deux observable a obtenu une réponse de succès.

Comment gérer une réponse d'erreur à l'aide de l'opérateur Zip

16
Priyank Patel

Vous pouvez utiliser onErrorResumeNext pour renvoyer une valeur observable ou onErrorReturn pour renvoyer une valeur par défaut à Zip, par exemple:

Observable.Zip(
   responseOneObservable
       .onErrorReturn(new Func1<Throwable, ResponseOne>() {
        @Override
        public ResponseOne call(final Throwable throwable) {
            return new ResponseOne();
        }
    }),
   responseTwoObservable
       .onErrorReturn(new Func1<Throwable, ResponseTwo>() {
        @Override
        public ResponseTwo call(final Throwable throwable) {
            return new ResponseTwo();
        }
    }),
   ...

Voir onError processing pour plus d’informations.

24
EgorD

Vous pouvez renvoyer la réponse par défaut de l'une des deux variables observables avec l'opérateur onErrorResumeNext.

Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
    .onErrorResumeNext(throwable -> {/*some default value*/})
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());

Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
    .onErrorResumeNext(throwable -> {/*some default value*/})
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());

Voir aussi Traitement des erreurs dans RxJava - Dan Lew

2
Alexander Perfilyev

Vous devez utiliser onErrorResumeNext sur les observables à simple compression pour leur demander d'émettre un élément par défaut en cas d'erreur.

Reportez-vous à Opérateurs de gestion des erreurs

0
Marco Righini