Search code examples
javaandroidrx-javarx-java2rxjs-observables

RxJava - How to make flatmap continue if one of the observables causes an error?


I'm creating an app that takes a list of apps installed on the device and checks for version updates from the google play store.

This is my method to get the app information based on package name:

    public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
        return Observable.fromIterable(apps)
            .flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName));
    }

It works fine if the package is actually on the google play store, but it returns retrofit2.adapter.rxjava2.HttpException: HTTP 404 if the package name is not found (ie: sideloaded app)

This is my method to handle the observables:

 updatesViewController.getUpdates(apps)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .as(AutoDispose.autoDisposable(ViewScopeProvider.from(this)))
            .subscribe(responseItem -> responseList.add(responseItem),
                    throwable -> responseList.add(null), //404's here, doesn't do the onComplete at all.
                    () -> { // onComplete
                        for (int i = 0; i < apps.size(); ++i) {
                          if (responseList.get(i) != null && apps.get(i).isLowerVersion(responseList.get(i)) {
                              doSomething();
                          }
                     });

If all the apps are on the playstore, this works as intended. I want to make it so that if one or more of the apps are not found in the playstore, it can still doSomething() on the apps that are found, while ignoring the apps that aren't. Any help is appreciated!


Solution

  • My solution to this problem:

    I added a .onErrorResumeNext(Observable.empty()); which effectively skips the items that cause errors.

    public Observable<DetailsResponse> getUpdates(@NonNull List<ApplicationInfo> apps) {
         return Observable.fromIterable(apps)
            .flatMap(appInfo -> googlePlayApiService.getDetails(appInfo.packageName)
            .onErrorResumeNext(Observable.empty()));
    }
    

    Then in onComplete, instead of looping through all my apps, I only loop through the ones that are in the responseList, which was mostly just a logic error, not an rxJava error.