パルカワ2

PerlとRubyとイチャラブ

複数のデータソースから値を取り出すのをRxJavaのconcatで実現する場合のエラー処理

blog.danlew.net

複数のデータソースから値を取り出すのをRxのconcatで実現するという記事を見て、なるほど!!と思った。ただ、エラーになった場合どうなるのかわからなかったので確認した。

以下のようなコードの場合は、localSourceのErrorがonErrorにきてremoteSourceのErrorはこない。(というか、そもそもremoteSourceが実行されない)

Single<String> localSource = Single.create(emitter -> {
    emitter.onError(new RuntimeException("1個目のError"));
});

Single<String> remoteSource = create(emitter -> {
    emitter.onError(new RuntimeException("2個目のError"));
});

Single.concat(localSource, remoteSource).subscribe(string -> Log.i("TEST", string), Throwable::printStackTrace);

localSourceの読み込みに失敗したら、remoteSourceのデータを使いたいと思ったので、onErrorReturnとfilterでどうにか出来ないかと思った。これでremoteSourceのErrorがonErrorにくるようになる。ちなみに空文字なのは、RxJavaはnullを許容しないからです。

Single.concat(localSource.onErrorReturn(__ -> ""), remoteSource)
  .filter(""::equals)
  .subscribe(string -> Log.i("TEST", string), Throwable::printStackTrace);

またはObservableにしてempty()を使うというのがコード自体は長くなるがfilterしなくていい(変な仕様を作らなくてよい)ので良い気がした。

Observable.concat(localSource.toObservable().onErrorResumeNext(Observable.empty()), remoteSource.toObservable())
                .first("default")
                .subscribe(string -> Log.i("TEST", string), Throwable::printStackTrace);

もっといい方法ありそう!!! あったら教えてください

追記:
教えて頂いた!Maybe!onErrorComplete() そもそも知らなかった…