RxJavaでエラーが発生したときに◯回リトライする
ただのメモ書き。
やりたいこと
エラーが発生したときに◯回リトライして、エラー終了 or 正常終了する 全てはこのあたりにまとまっている。ただの蛇足
試したこと
目的は、Httpリクエストにつけてるtokenの期限切れ時にリトライするようなパターンを想定している。 書いてみたら、結局は上記の記事の内容で十分網羅出来ている
正常終了のパターン
@RunWith(JUnit4::class) class MyTest { fun someFunction() { System.out.println("some") } @Test fun hoge() { val exception = mock(HttpException::class.java).apply { `when`(code()).thenReturn(HttpURLConnection.HTTP_UNAUTHORIZED) } Observable.create<String> { it.onNext("1") it.onNext("2") it.onError(exception) }.retryWhen { upstream -> upstream.take(3).doOnNext { if (it is HttpException) { when (it.code()) { HttpURLConnection.HTTP_UNAUTHORIZED -> someFunction() } } } }.subscribe({ System.out.println(it) }, { System.out.println("error") }, { System.out.println("completed") }) } }
結果
1 2 some 1 2 some 1 2 some completed
エラー終了のパターン。こちらはcomposeを利用するようにしてみてる
@RunWith(JUnit4::class) class MyTest { fun someFunction() { System.out.println("some") } @Test fun fuga() { val exception = mock(HttpException::class.java).apply { `when`(code()).thenReturn(HttpURLConnection.HTTP_UNAUTHORIZED) } Single.create<String> { emitter -> System.out.println("st") emitter.onError(exception) } .compose(TokenRefreshTransformer<String>()) .subscribe({ System.out.println(it) }, { System.out.println("error occurred") }) } }
class TokenRefreshTransformer<T> : SingleTransformer<T, T> { override fun apply(upstream: Single<T>): SingleSource<T> = upstream.retry { count, it -> refresh(count, it) } private fun refresh(count: Int, throwable: Throwable): Boolean { if (count < 3) { if (throwable is HttpException) { when (throwable.code()) { HttpURLConnection.HTTP_UNAUTHORIZED -> someFunction() } } return true } return false } private fun someFunction() { System.out.println("super!") } }
結果
st super! st super! st error occurred