Hi,
I am bit lost what are the ways to implement retry logic.
I have a simple code like this
val response = runBlocking {
val mutation = apolloClient.mutation(
UpdateCollectionMainStageMutation(
input = it.first,
version = version,
metadata = Optional.present(it.second)
)
)
mutation.execute()
}
I see the there were some suggestions from old github comments, but not sure if they are accurate.
I see in the doc for react Retry Link - Apollo GraphQL Docs , is there something for Kotlin?
Hi!
If you only need to retry certain operations on a case-by-case basis, you can simply enclose the call to execute
into a try catch
block and treat the exception here. Also check response.errors
for GraphQL errors. It could be an extension on ApolloClient
to be nicer to use, something like:
suspend fun <T : Query.Data> ApolloClient.tryQuery(query: Query<T>, retryCount: Int): T? {
for (i in 0..retryCount) {
val response = try {
this.query(query).execute()
} catch (e: Exception) {
// Log the errors
continue
}
if (response.hasErrors()) {
// Log the errors
continue
}
return response.data
}
return null
}
If you want to have this behavior for all operations, you can use an ApolloInterceptor for this, which will be automatically be called for all operations. Something like this:
class RetryInterceptor(private val retryCount: Long) : ApolloInterceptor {
override fun <D : Operation.Data> intercept(
request: ApolloRequest<D>,
chain: ApolloInterceptorChain
): Flow<ApolloResponse<D>> {
return chain.proceed(request)
.onEach { response ->
if (response.hasErrors()) {
throw Exception("There were GraphQL errors")
}
}
.retry(retryCount) { true }
}
}
and use it on your client like this:
val apolloClient = ApolloClient.Builder()
.serverUrl("https://...")
.addInterceptor(RetryInterceptor(3))
.build()