【Kotlin/Android】RxJavaでエラーハンドリングする方法!

【Kotlin/Android】RxJavaでエラーハンドリングする方法!

この記事からわかること

  • Android Studio/KotlinRxJava使い方
  • onErrorReturn/onErrorReturnItem/onErrorResumeNext/onExceptionResumeNextの違いと使い方
  • retry/retryWhen/doOnError違いと使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

RxJavaのエラーハンドリング

RxJavaでストリームにエラーが流れた場合にハンドリングするメソッドは色々用意されています。汎用性の高いものの使い方と特徴を軽くまとめていきたいと思います。

onErrorReturn

onErrorReturnエラーが発生したときにデフォルト値を返すメソッドです。ラムダ式の中では流れてきたエラーを参照でき、返す値を動的に指定することができます。またonErrorReturnを使用するとエラーが発生してもストリームは正常に進んでいくので下流にdoOnErrorなどがあっても反応しません。

val observable = Observable.create<Int> { emitter ->
    Log.d("RxJava", "ストリーム開始")
    emitter.onNext(1)
    emitter.onNext(2)
    emitter.onError(RuntimeException("エラー発生"))
}

observable
    .onErrorReturn { throwable -> 
      // エラーの種類によって返す値をコントロールできる
      if (throwable is RuntimeException) {
        -1 
      } else {
        -2
      }
    }
    .doOnSubscribe { Log.d("RxJava", "観測開始") }
    .doOnNext { Log.d("RxJava", "Received: $it") }
    .doOnError { Log.d("RxJava", "Error: ${it.message}") }
    .doOnComplete { Log.d("RxJava", "Completed") }
    .subscribe(
        { /* onNext */ },
        { /* onError */ },
        { /* onComplete */ }
    )
    .addTo(compositeDisposable)

出力

観測開始
ストリーム開始
Received: 1
Received: 2
Received: -1
Completed

onErrorReturnItem

onErrorReturnItemonErrorReturnと同じくエラーが発生したときにデフォルト値を返すメソッドです。違いはonErrorReturnラムダ式内で動的に返す値を操作できたのに対しonErrorReturnItem事前に指定された固定値を返します。

observable
    .onErrorReturnItem(3) // 固定値を返す
    .doOnSubscribe { Log.d("RxJava", "観測開始") }
    .doOnNext { Log.d("RxJava", "Received: $it") }
    .doOnError { Log.d("RxJava", "Error: ${it.message}") }
    .doOnComplete { Log.d("RxJava", "Completed") }
    .subscribe(
        { /* onNext */ },
        { /* onError */ },
        { /* onComplete */ }
    )
    .addTo(compositeDisposable)

出力

観測開始
ストリーム開始
Received: 1
Received: 2
Received: 3
Completed

onErrorResumeNext

onErrorResumeNextエラーが発生したときに別のObservableを返すメソッドです。ラムダ式の引数で取得したエラーをThrowable型で参照することができます。

 observable
    // 引数は明示的に型を指定しないとエラーになる
    .onErrorResumeNext { throwable: Throwable ->
        Log.d("RxJava", "Error: ${throwable.message}")
        // 異なるObservableを返す
        Observable.just(4, 5, 6)
    }
    .doOnSubscribe { Log.d("RxJava", "観測開始") }
    .doOnNext { Log.d("RxJava", "Received: $it") }
    .doOnError { Log.d("RxJava", "Error: ${it.message}") }
    .doOnComplete { Log.d("RxJava", "Completed") }
    .subscribe(
        { /* onNext */ },
        { /* onError */ },
        { /* onComplete */ }
    )
    .addTo(compositeDisposable)

出力

観測開始
ストリーム開始
Received: 1
Received: 2
Received: 4
Received: 5
Received: 6
Completed

onExceptionResumeNext

onExceptionResumeNextExceptionが発生したときに別のObservableを返すメソッドです。発生したエラーがExceptionExceptionを継承した独自エラーの場合のみ動作するのでRuntimeExceptionThrowableでは動作しません。

val observable = Observable.create { emitter ->
    Log.d("RxJava", "ストリーム開始")
    emitter.onNext(1)
    emitter.onNext(2)
    // RuntimeExceptionでは発生しない
    // emitter.onError(RuntimeException("エラー発生"))
    emitter.onError(Exception("エラー発生"))
}

observable
    .onExceptionResumeNext(Observable.just(4, 5, 6))
    .doOnSubscribe { Log.d("RxJava", "観測開始") }
    .doOnNext { Log.d("RxJava", "Received: $it") }
    .doOnError { Log.d("RxJava", "Error: ${it.message}") }
    .doOnComplete { Log.d("RxJava", "Completed") }
    .subscribe(
        { /* onNext */ },
        { /* onError */ },
        { /* onComplete */ }
    )
    .addTo(compositeDisposable)

出力

観測開始
ストリーム開始
Received: 1
Received: 2
Received: 4
Received: 5
Received: 6
Completed

retry/retryWhen

retry/retryWhenエラーが発生したときに再試行するメソッドです。ストリームにエラーが発生した場合にストリームを最初から再試行することができます。詳細は以下の記事を参考にしてください。

.retry(3)

doOnError

doOnErrorエラーが発生したときにコールバックを実行するするメソッドです。RxJavaでは特定のイベントが発生したときにコールバックを実行するDo系のメソッドが他にも用意されているので詳細は以下の記事を参考にしてください。

.doOnError { Log.d("RxJava", "Error: ${it.message}") }

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index