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

この記事からわかること
- Android Studio/KotlinでRxJavaの使い方
- onErrorReturn/onErrorReturnItem/onErrorResumeNext/onExceptionResumeNextの違いと使い方
- retry/retryWhen/doOnErrorの違いと使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
RxJavaのエラーハンドリング
RxJavaでストリームにエラーが流れた場合にハンドリングするメソッドは色々用意されています。汎用性の高いものの使い方と特徴を軽くまとめていきたいと思います。
- onErrorReturn
- onErrorReturnItem
- onErrorResumeNext
- onExceptionResumeNext
- retry
- retryWhen
- doOnError
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
onErrorReturnItem
はonErrorReturn
と同じくエラーが発生したときにデフォルト値を返すメソッドです。違いは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
onExceptionResumeNext
はExceptionが発生したときに別のObservableを返すメソッドです。発生したエラーがException
やException
を継承した独自エラーの場合のみ動作するのでRuntimeException
やThrowable
では動作しません。
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}") }
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。