Each time a client disconnects I get this message ...
# rsocket
m
Each time a client disconnects I get this message that is flooding my logs. Any idea how I can ignore it?
Copy code
Caused by: kotlinx.coroutines.channels.ClosedReceiveChannelException: Channel was closed
	at kotlinx.coroutines.channels.Closed.getReceiveException(AbstractChannel.kt:1108)
	at kotlinx.coroutines.channels.AbstractChannel$ReceiveElement.resumeReceiveClosed(AbstractChannel.kt:913)
	at kotlinx.coroutines.channels.AbstractSendChannel.helpClose(AbstractChannel.kt:342)
	at kotlinx.coroutines.channels.AbstractSendChannel.close(AbstractChannel.kt:271)
	at kotlinx.coroutines.channels.SendChannel$DefaultImpls.close$default(Channel.kt:93)
	at io.ktor.websocket.DefaultWebSocketSessionImpl$runIncomingProcessor$1.invokeSuspend(DefaultWebSocketSession.kt:204)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:234)
	at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:190)
	at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
	at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
	at kotlinx.coroutines.CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:513)
	at kotlinx.coroutines.channels.AbstractChannel$ReceiveHasNext.completeResumeReceive(AbstractChannel.kt:947)
	at kotlinx.coroutines.channels.AbstractSendChannel.offerInternal(AbstractChannel.kt:56)
	at kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:134)
	at io.ktor.websocket.RawWebSocketJvm$1.invokeSuspend(RawWebSocketJvm.kt:68)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
r
Define a
CoroutineExceptionHandler
as part of the scope the rsocket is created in, and ignore that error in there. In addition to that one, I also ignore
RSocketError.ConnectionError
and
RSocketError.ConnectionClose
. I log
IOException
at warn level and everything else at error level, and that seems to work well.
m
@rocketraman I have been trying that but I can't seem to reach the right scope. Note that I am on the server side. I tried adding a
CoroutineExceptionHandler
to the Ktor ApplicationEngineEnviroment and to the
GaiaRSocketAccepter
constructor but the handler is not triggered. Can you by any chance provide an example please?
r
Here is what I have done on the server side:
Copy code
val server = RSocketServer()
    val job = SupervisorJob()
    val scope = CoroutineScope(
      job + CoroutineExceptionHandler { coroutineContext, throwable ->
        // Workaround <https://github.com/rsocket/rsocket-kotlin/issues/226>
        if (throwable is ClosedReceiveChannelException ||
          throwable is RSocketError.ConnectionError ||
          throwable is RSocketError.ConnectionClose
        ) return@CoroutineExceptionHandler
        if (throwable is IOException) {
          log.warn(throwable) { "IO exception in planner API server context=$coroutineContext" }
        } else {
          log.error(throwable) { "Unexpected error happened in planner API server context=$coroutineContext" }
        }
      }
    )
    val acceptor = createAcceptor()
    <http://log.info|log.info> { "Start planning server at: ${config.hostPort}" }
    server.bindIn(
      scope,
      TcpServerTransport(config.host(), config.port(DEFAULT_PLANNER_SERVER_PORT)),
      acceptor
    )
I don't use Ktor though... I'm using RSocket directly.