Reputation: 3255
I'm using Rx2Apollo to make a graphql call:
private fun registerCardToken(token: String): io.reactivex.Observable<RegisterCardTokenMutation.RegisterCreditCard> {
val apolloCall = apolloClient().mutate(RegisterCardTokenMutation.builder().token(token).build())
return Rx2Apollo.from(apolloCall).map {
(it.data() as RegisterCardTokenMutation.Data).registerCreditCard()
}.doOnError({ error ->
//Log.e("registerCardToke", error.message)
})
}
This works well, but I want to handle specific error and retry this onces. I have tried to work around this using retryWhen
and retry
, but not able to write any executable code yet.
The retry persons a token refresh before performing the actual retry. Here's the token refresh sample:
private fun refreshBearerToken(callback: OnCompleteListener<GetTokenResult>) {
FirebaseAuth.getInstance().currentUser?.getIdToken(true)?.addOnCompleteListener(callback)
}
Upvotes: 0
Views: 439
Reputation: 70007
First, you have to turn refreshBearerToken
into an Observable
val refreshTokenSource = Observable.create({ emitter ->
FirebaseAuth.
getInstance().
currentUser?.
getIdToken(true)?.
addOnCompleteListener({ task ->
if (task.isSuccessful()) {
emitter.onNext(task.getResult())
emitter.onComplete()
} else {
emitter.onError(task.getException())
}
})
})
Second, use some external reference holding the current token and conditionally use it before calling registerCardToken
:
val currentToken = AtomicReference<String>()
val registerCardTokenObservable = Observable.defer({
val token = currentToken.get()
if (token == null) {
return refreshTokenSource
.doOnNext({ currentToken.set(it) })
.flatMap({ registerCardToken(it) })
}
return registerCardToken(token)
})
.retry({ error ->
if ((error is IOException) || (error.getMessage().contains("network")) {
currentToken.set(null)
return true
}
return false
})
Upvotes: 1