When I go to close the web socket, I sometimes get an exception of the following form. It doesn't seem to happen every time and I can't tell what is triggering it. My only thought is that perhaps the other side closed the socket first, but I don't know why that would be the case and I'm not sure there is a way to detect it (at least with the Hato API; perhaps with the underlying JDK API). Oddly, from the stack trace, it looks like the code is trying to write to the socket and that's resulting in a "broken pipe." Finally, note that this does get reported through the :on-error handler.
#error {
:cause Broken pipe
:via
[{:type java.io.IOException
:message Broken pipe
:at [sun.nio.ch.SocketDispatcher writev0 SocketDispatcher.java -2]}]
:trace
[[sun.nio.ch.SocketDispatcher writev0 SocketDispatcher.java -2]
[sun.nio.ch.SocketDispatcher writev SocketDispatcher.java 66]
[sun.nio.ch.IOUtil write IOUtil.java 227]
[sun.nio.ch.IOUtil write IOUtil.java 158]
[sun.nio.ch.SocketChannelImpl write SocketChannelImpl.java 574]
[java.nio.channels.SocketChannel write SocketChannel.java 660]
[jdk.internal.net.http.SocketTube writeAvailable SocketTube.java 1244]
[jdk.internal.net.http.SocketTube$InternalWriteSubscriber tryFlushCurrent SocketTube.java 354]
[jdk.internal.net.http.SocketTube$InternalWriteSubscriber onNext SocketTube.java 317]
[jdk.internal.net.http.SocketTube onNext SocketTube.java 135]
[jdk.internal.net.http.SocketTube onNext SocketTube.java 58]
[jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher run1 SubscriberWrapper.java 316]
[jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher run SubscriberWrapper.java 259]
[jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask run SequentialScheduler.java 182]
[jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149]
[jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233]
[jdk.internal.net.http.common.SubscriberWrapper outgoing SubscriberWrapper.java 232]
[jdk.internal.net.http.common.SubscriberWrapper outgoing SubscriberWrapper.java 198]
[jdk.internal.net.http.common.SSLFlowDelegate$Writer sendResultBytes SSLFlowDelegate.java 962]
[jdk.internal.net.http.common.SSLFlowDelegate$Writer processData SSLFlowDelegate.java 845]
[jdk.internal.net.http.common.SSLFlowDelegate$Writer$WriterDownstreamPusher run SSLFlowDelegate.java 721]
[jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149]
[jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233]
[jdk.internal.net.http.common.SSLFlowDelegate$Writer incoming SSLFlowDelegate.java 745]
[jdk.internal.net.http.common.SubscriberWrapper incomingCaller SubscriberWrapper.java 438]
[jdk.internal.net.http.common.SubscriberWrapper onNext SubscriberWrapper.java 379]
[jdk.internal.net.http.common.SubscriberWrapper onNext SubscriberWrapper.java 57]
[jdk.internal.net.http.common.SSLTube onNext SSLTube.java 662]
[jdk.internal.net.http.common.SSLTube onNext SSLTube.java 68]
[jdk.internal.net.http.RawChannelTube write RawChannelTube.java 356]
[jdk.internal.net.http.websocket.TransportImpl write TransportImpl.java 114]
[jdk.internal.net.http.websocket.TransportImpl$SendTask tryCompleteWrite TransportImpl.java 607]
[jdk.internal.net.http.websocket.TransportImpl$SendTask run TransportImpl.java 557]
[jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149]
[jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280]
[jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233]
[jdk.internal.net.http.websocket.TransportImpl sendClose TransportImpl.java 271]
[jdk.internal.net.http.websocket.WebSocketImpl sendClose0 WebSocketImpl.java 345]
[jdk.internal.net.http.websocket.WebSocketImpl sendClose WebSocketImpl.java 315]
[hato.websocket$close_BANG_ invokeStatic websocket.clj 153]
[hato.websocket$close_BANG_ invoke websocket.clj 147]
[hato.websocket$close_BANG_ invokeStatic websocket.clj 151]
[hato.websocket$close_BANG_ invoke websocket.clj 147]
... application stack frames...
}
When I go to close the web socket, I sometimes get an exception of the following form. It doesn't seem to happen every time and I can't tell what is triggering it. My only thought is that perhaps the other side closed the socket first, but I don't know why that would be the case and I'm not sure there is a way to detect it (at least with the Hato API; perhaps with the underlying JDK API). Oddly, from the stack trace, it looks like the code is trying to write to the socket and that's resulting in a "broken pipe." Finally, note that this does get reported through the
:on-errorhandler.#error { :cause Broken pipe :via [{:type java.io.IOException :message Broken pipe :at [sun.nio.ch.SocketDispatcher writev0 SocketDispatcher.java -2]}] :trace [[sun.nio.ch.SocketDispatcher writev0 SocketDispatcher.java -2] [sun.nio.ch.SocketDispatcher writev SocketDispatcher.java 66] [sun.nio.ch.IOUtil write IOUtil.java 227] [sun.nio.ch.IOUtil write IOUtil.java 158] [sun.nio.ch.SocketChannelImpl write SocketChannelImpl.java 574] [java.nio.channels.SocketChannel write SocketChannel.java 660] [jdk.internal.net.http.SocketTube writeAvailable SocketTube.java 1244] [jdk.internal.net.http.SocketTube$InternalWriteSubscriber tryFlushCurrent SocketTube.java 354] [jdk.internal.net.http.SocketTube$InternalWriteSubscriber onNext SocketTube.java 317] [jdk.internal.net.http.SocketTube onNext SocketTube.java 135] [jdk.internal.net.http.SocketTube onNext SocketTube.java 58] [jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher run1 SubscriberWrapper.java 316] [jdk.internal.net.http.common.SubscriberWrapper$DownstreamPusher run SubscriberWrapper.java 259] [jdk.internal.net.http.common.SequentialScheduler$LockingRestartableTask run SequentialScheduler.java 182] [jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149] [jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233] [jdk.internal.net.http.common.SubscriberWrapper outgoing SubscriberWrapper.java 232] [jdk.internal.net.http.common.SubscriberWrapper outgoing SubscriberWrapper.java 198] [jdk.internal.net.http.common.SSLFlowDelegate$Writer sendResultBytes SSLFlowDelegate.java 962] [jdk.internal.net.http.common.SSLFlowDelegate$Writer processData SSLFlowDelegate.java 845] [jdk.internal.net.http.common.SSLFlowDelegate$Writer$WriterDownstreamPusher run SSLFlowDelegate.java 721] [jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149] [jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233] [jdk.internal.net.http.common.SSLFlowDelegate$Writer incoming SSLFlowDelegate.java 745] [jdk.internal.net.http.common.SubscriberWrapper incomingCaller SubscriberWrapper.java 438] [jdk.internal.net.http.common.SubscriberWrapper onNext SubscriberWrapper.java 379] [jdk.internal.net.http.common.SubscriberWrapper onNext SubscriberWrapper.java 57] [jdk.internal.net.http.common.SSLTube onNext SSLTube.java 662] [jdk.internal.net.http.common.SSLTube onNext SSLTube.java 68] [jdk.internal.net.http.RawChannelTube write RawChannelTube.java 356] [jdk.internal.net.http.websocket.TransportImpl write TransportImpl.java 114] [jdk.internal.net.http.websocket.TransportImpl$SendTask tryCompleteWrite TransportImpl.java 607] [jdk.internal.net.http.websocket.TransportImpl$SendTask run TransportImpl.java 557] [jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask run SequentialScheduler.java 149] [jdk.internal.net.http.common.SequentialScheduler$SchedulableTask run SequentialScheduler.java 207] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 280] [jdk.internal.net.http.common.SequentialScheduler runOrSchedule SequentialScheduler.java 233] [jdk.internal.net.http.websocket.TransportImpl sendClose TransportImpl.java 271] [jdk.internal.net.http.websocket.WebSocketImpl sendClose0 WebSocketImpl.java 345] [jdk.internal.net.http.websocket.WebSocketImpl sendClose WebSocketImpl.java 315] [hato.websocket$close_BANG_ invokeStatic websocket.clj 153] [hato.websocket$close_BANG_ invoke websocket.clj 147] [hato.websocket$close_BANG_ invokeStatic websocket.clj 151] [hato.websocket$close_BANG_ invoke websocket.clj 147] ... application stack frames... }