Handling Networks Errors
Building robust mobile applications requires dealing with spotty internet connectivity and/or backend errors.
By default, ApolloClient exposes all network errors. You are responsible for handling them. A typical strategy is to display a generic error and suggest the user retry later.
ApolloClient exposes APIs to retry failed operations and/or get the status of the network.
retryOnError()
To make your applications more robust, you may opt-in retrying failed operations.
To do so, call retryOnError(true):
1val apolloClient = ApolloClient.Builder()
2 .serverUrl("https://example.com/graphql")
3 .retryOnError(true)
4 .build()
5
6// retries up to three times before giving up
7val response = apolloClient.query(myQuery).execute()By default, retryOnError(true) has the following behavior:
queries and mutations are retried up to three times, with exponential backoff.
subscriptions are retried as long as the scope is running, with exponential backoff, capped at 60 seconds.
RetryStrategy
You may customize the default strategy using a RetryStrategy. The following example shows a RetryStrategy that waits 10 seconds between each retry:
1val apolloClient = ApolloClient.Builder()
2 .retryOnErrorInterceptor(RetryOnErrorInterceptor(networkMonitor) { state, request, response ->
3 val exception = response.exception
4 if (exception == null) {
5 // No error, do not retry
6 return@RetryOnErrorInterceptor false
7 }
8
9 delay(10.seconds)
10 return@RetryOnErrorInterceptor true
11 })
12 .build()NetworkMonitor
Android and Apple targets provide APIs to monitor the network state of your device:
ConnectivityManager on Android targets.
NWPathMonitor on Apple targets.
You can configure your ApolloClient to use these APIs using a NetworkMonitor:
1// androidMain
2val networkMonitor = NetworkMonitor(context)
3
4// appleMain
5val networkMonitor = NetworkMonitor()
6
7// commonMain
8val apolloClient = ApolloClient.Builder()
9 .serverUrl("https://example.com/graphql")
10 .retryOnErrorInterceptor(RetryOnErrorInterceptor(networkMonitor))
11 .build()
12
13// once you're done with your `ApolloClient`
14networkMonitor.close()When a NetworkMonitor is configured, the default RetryStrategy waits for the network to be back online before retrying subscriptions. This improves the latency of reconnecting subscriptions.
failFastIfOffline
When a NetworkMonitor is configured, use failFastIfOffline(true) to avoid executing requests when the device is offline:
1// Opt-in `failFastIfOffline` on all queries
2val apolloClient = ApolloClient.Builder()
3 .serverUrl("https://example.com/graphql")
4 .retryOnErrorInterceptor(RetryOnErrorInterceptor(networkMonitor))
5 .failFastIfOffline(true)
6 .build()
7
8val response = apolloClient.query(myQuery).execute()
9println(response.exception?.message)
10// "The device is offline"In addition to waiting for the network to be back online before retrying subscriptions, this also has the following benefits:
Network requests fail eagerly, without going to the OS layers (DNS, etc...). This reduces error latency in bad network conditions.
ApolloOfflineExceptionis returned instead of a more genericApolloNetworkException. This gives the user more precise error messages.