2017-09-05 16 views
1

J'ai du mal à trouver comment générer une erreur de réseau de la couche de données à la couche de vue. J'utilise Room avec RxJava2 et Retrofit2. J'implémente le modèle de référentiel en tant que local-first, donc j'interroge les données locales, tout en récupérant à partir de la télécommande, et en mettant à jour les données locales si nécessaire. Dans le code, ce serait:Gérer l'erreur de réseau sur Retrofit + RxJava2 + Salle

public Flowable<List<DEvent>> getAll() { 
    return db.dEventDataStore().getAll() 
     .doOnSubscribe(new Consumer<Subscription>() { 
      @Override 
      public void accept(final Subscription subscription) throws Exception { 
       dEventApi.getAll().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(new MaybeObserver<List<DEvent>>() { 
         @Override 
         public void onSubscribe(@NonNull Disposable disposable) { 
          Timber.d("Remote onSubscribe"); 
         } 

         @Override 
         public void onSuccess(@NonNull List<DEvent> dEvents) { 
          Timber.d("Remote onSuccess!"); 
          db.dEventDataStore().insertAll(dEvents); 
         } 

         @Override 
         public void onError(@NonNull Throwable throwable) { 
          Timber.d("Remote onError!"); 
         } 

         @Override 
         public void onComplete() { 
          Timber.d("Remote onComplete!"); 
         } 
        } 
       ); 
      } 
     }); 
} 

Et dans la couche de vue:

mDisposable.add(repo.getAll() 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Consumer<List<DEvent>>() { 
       @Override 
       public void accept(List<DEvent> dEvents) throws Exception { 
        Timber.d("OnNext!!"); 
        mView.showEvents(dEvents); 
       } 
      }, new Consumer<Throwable>() { 
       @Override 
       public void accept(Throwable throwable) throws Exception { 
        Timber.e("Error on getting DEvents - " + Log.getStackTraceString(throwable)); 
       } 
      })); 

Comment puis-je émettre que throwable?

Répondre

1

Vous ne chaînez pas ces observables ici - ainsi une erreur de l'API Observable ne se propagera pas dans le flux vers la couche de vue. (d'ailleurs je ne suis pas sûr de savoir comment Chambre fonctionne mais vous interrogera deux fois pour les mises à jour DB)

Si je comprend bien, db.dEventDataStore().getAll() créé par chambre donc ce Flowable est infini, écouter DB changements et émettre tout changement. donc vous voulez interroger le serveur, et dans le cas de données mettre à jour le DB et attendez l'émission de DB de la salle fluide.

Dans ce cas, vous pouvez le faire en parallèle en utilisant merge, et l'API. Peut-être, ne faites passer que les erreurs en ignorant les éléments qu'il émet. de cette façon, nous n'obtiendrons les émissions de données de Room DB qu'à l'aval, tout en recevant des notifications d'erreurs de serveur.

public Flowable<List<DEvent>> getAll() { 
    return Flowable.merge(
      db.dEventDataStore().getAll(), 
      dEventApi.getAll() 
        .doAfterSuccess(dEvents -> db.dEventDataStore().insertAll(dEvents)) 
        .ignoreElement() 
        .toFlowable() 
    ); 
} 
+0

Merci! Fonctionne comme prévu, rendant xxxAPIDataSource (retrofit) return Flowable – webo80