Hello :wave:, we are seeing a few crashes around w...
# apollo-kotlin
a
Hello 👋, we are seeing a few crashes around websockets. Stack trace in 🧵, I couldn't find this reported anywhere so wondering if something is wrong with our setup.
Copy code
Fatal Exception: java.lang.NullPointerException:
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport$supervise$3.invokeSuspend(WebSocketNetworkTransport.kt:225)
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport$supervise$3.invoke(WebSocketNetworkTransport.kt:13)
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport$supervise$3.invoke(WebSocketNetworkTransport.kt:13)
       at kotlinx.coroutines.intrinsics.UndispatchedKt.startCoroutineUndispatched(Undispatched.kt:20)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.java:360)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:134)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(BuildersKt__Builders_common.kt:52)
       at kotlinx.coroutines.BuildersKt.launch(Builders.kt:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(BuildersKt__Builders_common.kt:43)
       at kotlinx.coroutines.BuildersKt.launch$default(Builders.kt:1)
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport.supervise(WebSocketNetworkTransport.kt:224)
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport.access$supervise(WebSocketNetworkTransport.kt:58)
       at com.apollographql.apollo.network.ws.WebSocketNetworkTransport$supervise$1.invokeSuspend(WebSocketNetworkTransport.kt:13)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.internal.ScopeCoroutine.afterResume(Scopes.kt:35)
       at kotlinx.coroutines.AbstractCoroutine.resumeWith(AbstractCoroutine.kt:101)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
       at kotlinx.coroutines.internal.LimitedDispatcher$Worker.run(LimitedDispatcher.kt:113)
       at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:89)
       at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.java:586)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:829)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:717)
       at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:704)
m
Hi 👋 Sorry you're bumping into that.
That code is indeed one of the most convoluted parts which I'm trying to get rid of. Any chance you can try the experimental websockets? I'd like to make them the default in 5.0
a
No haven't tried as it's still experimental, but was looking for some short term solutions if there are any.
I think we can wait for the upgrade as it's not a huge number of crashes. And also wanted to rule out it's not our setup that's causing the issue.
m
Out of curiosity, what is your setup like? Especially, what protocol are you using?
And any specific retry mechanism you have?
a
Yes
Copy code
val webSocketNetworkTransport = WebSocketNetworkTransport.Builder()
    .serverUrl(webSocketUrl)
    .okHttpClient(okHttpClient)
    .protocol(
        SubscriptionWsProtocol.Factory(
            connectionPayload = {
                authorizationHeaders()
            }
        )
    )
    .reopenWhen { throwable, attempt ->
        if (throwable is DisableSubscriptionException) {
            reconnectSignalChannel.receive()
        }
        delayAndShouldRetryWithBackoff(attempt + 1) // Apollo starts their counting from 0
    }
    .build()
thank you color 1
The exponential retry starts with 2 sec up until 32 secs