RxJavaの処理中に特定のエラー発生時、別のRx処理を呼び出してから本来の処理をリトライしたい
概要
特定のRxJavaの処理中(repository.fetchModelByApi()
)に特定のエラーを検知したときのみ別のRxの処理(subUseCase.refreshToken()
)をretryWhen()
内で呼び出し、その結果を以ってrepository.fetchModelByApi()
の処理を再開する実装を行いたいのですが、後述のエラーが発生してビルドが通らず困っております。
この場合、どの様に実装するのが適切かご教示いただけるとありがたいです。
使用ライブラリ
- rxjava:2.2.8
- rxandroid:2.1.1
- rxkotlin:2.3.0
実装コード抜粋
fun fetchModel(): Flowable<Result<Model>> {
return repository.fetchModelByApi(token)
.retryWhen { errors ->
// リトライ時に呼び出したい処理
val tokenRefresh = subUseCase.refreshToken()
Flowable.zip(errors, tokenRefresh, BiFunction { throwable, tokenRefresh ->
val response = ErrorResponse.form(throwable) ?: Flowable.error(throwable)
when (response.status) {
// 特定のエラーの場合のみ別のRx処理を呼び出してから本来の処理をリトライ
ErrorResponse.Status.UNAUTHORIZED -> {
when {
(tokenRefresh is Result.Failure) -> {
Result.failure(throwable)
}
(tokenRefresh is Result.Success) -> {
Result.success(true)
}
else -> {
Result.progress()
}
}
}
else -> Result.failure(throwable)
}
})
}
.map {
Translator.toModel(it)
}
.filter { token.isNotEmpty() }
.toFlowable()
.compose { item ->
item.map { Result.success(it) }
.onErrorReturn { Result.failure(it) }
.startWith(Result.progress())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
ビルド時のエラーログ
e: /xxx/HogeUseCase.kt: (188, 30): Type inference failed: Not enough information to infer parameter R in fun <T1 : Any!, T2 : Any!, R : Any!> zip(p0: Publisher<out T1!>!, p1: Publisher<out T2!>!, p2: BiFunction<in T1!, in T2!, out R!>!): Flowable<R!>
Please specify it explicitly.
e: /xxx/HogeUseCase.kt: (188, 56): Type inference failed: Not enough information to infer parameter R in fun <T1 : Any!, T2 : Any!, R : Any!> BiFunction(function: (T1, T2) -> R): BiFunction<T1, T2, R>
Please specify it explicitly.
e: /xxx/HogeUseCase.kt: (189, 82): Type inference failed. Expected type mismatch: inferred type is Flowable<(???..???)> but ErrorResponse was expected
e: /xxx/HogeUseCase.kt: (204, 44): Type inference failed: Not enough information to infer parameter T in fun <T> failure(e: Throwable): Result<T>
Please specify it explicitly.