Using http4s-ember-server on one of my applications I notice from time to time these exceptions appearing in my server's logs.
What is odd about them is that they don't follow my logger's appender or formatting style, they are just plain text like this, these stack lines go in separate lines so my kubernetes receives them as separate log messages while my normal exceptions and any application logs are formatted into a JSON, even exceptions are nicely in one block. So this must be coming from something low level.
I also noticed, only 1 of my 3 very similar applications throws these, so it can't be the meta/health, ready or buildinfo endpoints.
java.nio.channels.ClosedChannelException
at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.begin(AsynchronousSocketChannelImpl.java:118)
at java.base/sun.nio.ch.AsynchronousSocketChannelImpl.shutdownInput(AsynchronousSocketChannelImpl.java:536)
at fs2.io.net.SocketCompanionPlatform$AsyncSocket.$anonfun$readChunk$3(SocketPlatform.scala:121)
at delay @ fs2.io.net.SocketCompanionPlatform$AsyncSocket.$anonfun$readChunk$2(SocketPlatform.scala:120)
at delay @ fs2.io.net.SocketCompanionPlatform$AsyncSocket.$anonfun$readChunk$1(SocketPlatform.scala:120)
at async @ fs2.io.net.SocketCompanionPlatform$AsyncSocket.readChunk(SocketPlatform.scala:114)
at flatMap @ fs2.io.net.SocketCompanionPlatform$BufferedReads.$anonfun$read$1(SocketPlatform.scala:82)
at delay @ fs2.io.net.SocketCompanionPlatform$BufferedReads.withReadBuffer(SocketPlatform.scala:52)
at flatten$extension @ org.http4s.ember.server.internal.Shutdown$$anon$1.<init>(Shutdown.scala:71)
at onError @ com.c1999.n1999.w1999.NWApp$.run(NWApp.scala:15) <- this is the only line that states my own code
at getAndSet @ org.typelevel.keypool.KeyPool$.destroy(KeyPool.scala:120)
Has anyone encountered such exceptions with http4s servers?
The source code around line 15 looks like
val program =
(for {
twoConfigs <- NWAppConfig
.load[IO]
.onError(error => logger.error(error)(show"failed to load config with: $error")) // line 15 here
.toResource
(appConfig, requestContextConfig) = twoConfigs
components <- NWComponents(appConfig, requestContextConfig)
_ <- logger.info("started").toResource
_ <- components.streamsJoined.compile.drain
.onError(error => logger.error(error)(s"error in nw: $error"))
.toResource
} yield ()).use_