Handle network error when using GraphQL subscription with Apollo on Android with Kotlin and flows

Viewed 813

I'm using Apollo GraphQL on Android. I'm using Apollo ver 3. I have a subscription and I can successfully subscribe and get the updates. The problem is that if I turn the fligth mode on the app crashes with the exception:

    java.lang.IllegalStateException: WeSocket queue full
        at com.apollographql.apollo3.network.ws.DefaultWebSocketEngine$open$3.send(OkHttpWebSocketEngine.kt:90)
        at com.apollographql.apollo3.network.ws.WsProtocol.sendMessageMapBinary(WsProtocol.kt:92)
        at com.apollographql.apollo3.network.ws.SubscriptionWsProtocol.stopOperation(SubscriptionWsProtocol.kt:69)
        at com.apollographql.apollo3.network.ws.WebSocketNetworkTransport$3.invokeSuspend(WebSocketNetworkTransport.kt:144)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)

I have tried to use catch on the returned flow but it doesn't work. This is what I do:

apolloClient.subscribe(ProfileSubscription()).execute().catch {  }

The .grapql file that defines the subscription is:

subscription Profile {
    syncStatus {
        offline
    }
}

and I create the Apollo client by calling:

ApolloClient.Builder()
        .networkTransport(
            WebSocketNetworkTransport(
                serverUrl = baseUrl
            )
        ).build()

The base url uses ws as a protocol:

ws://ec2-xx-xxx-xxx-xx.eu-west-2.compute.amazonaws.com:4000/graphql

How can I gracefully handle the exceptions?

1 Answers

I just handled the exception where I start the flow:

viewModelScope.launch(CoroutineExceptionHandler{ _, _ -> }) {
    profilesUpdatesUseCase.subscribe()
}

The method profilesUpdatesUseCase.subscribe() is the one that calls:

apolloClient.subscribe(ProfileSubscription()).execute()

Of course the ViewModel needs to eventually restart the flow when possible.

Related