Repository navigation
Log WebSocket server handler errors; answer bad handshakes with 400 - #1482
Merged
Merged
Conversation
WebSockets.listen! ran each connection in a task that nothing waits on. A handler that threw closed its connection with 1011 and the error was rethrown into that task, so it was never reported anywhere; an error from a check_origin callback was lost the same way. A malformed handshake request closed the connection without a response. Such errors are now logged as websocket server error, errors that come from the peer are not, and a malformed handshake gets 400 Bad Request. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1482 +/- ##
==========================================
+ Coverage 91.67% 91.80% +0.13%
==========================================
Files 31 31
Lines 13187 13305 +118
==========================================
+ Hits 12089 12215 +126
+ Misses 1098 1090 -8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…pgrade A ParseError or ProtocolError raised by the handler after the 101 was taken for a malformed handshake: the server wrote a 400 response into the upgraded connection after its close frame and did not log the handler's error. Only an error from reading the handshake request now gets 400; any later error that did not come from the peer is logged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md # src/http_websockets.jl # test/http_websocket_server_tests.jl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WebSockets.listen!serves each connection in a task that nothing waits on. Two failures in that task were silent:_serve_ws_session!closed the connection with 1011 and rethrew. The rethrown error ended the task and was never reported. A typo in a WebSocket handler showed up only as a client seeing 1011. An error thrown by acheck_origincallback was lost the same way.read_requestthrew on a malformed handshake, the connection closed without any response._serve_ws_conn!now catches what reaches it. AParseErrororProtocolErrorfrom reading the handshake request gets400 Bad Request. Only those errors get it: an error the handler raises after the 101, even aProtocolError, is logged, and no HTTP bytes follow the close frame. Errors that come from the peer are not logged: aWebSocketError(the peer closed or broke the protocol), EOF, a closed or TLS-failed connection, a timeout, or a reset or broken pipe. Anything else is logged at error level aswebsocket server error, with the exception and backtrace. The client still sees 1011 for a handler error, as before.Verification. New testset in
test/http_websocket_server_tests.jl. A handler that throwserror("handler bug")makes the client see 1011, and the server logs onewebsocket server errorrecord carrying thatErrorException. A handler that throwsHTTP.ProtocolErrorafter the upgrade is also logged, and the raw client sees the 101, a 1011 close frame and then EOF, with no HTTP response. A handshake with a malformed header line gets400 Bad Request. On master no record is logged and the reply is empty. Locally,http_websocket_server_tests.jl(73),http_websocket_integration_tests.jlandhttp_websocket_client_tests.jlpass.Review.
_serve_ws_session!still closes the WebSocket before rethrowing, so the 1011 close frame is unchanged.isokerrors (1000, 1001, 1005) are not rethrown, so a normal close or a server shutdown logs nothing. The newcatchis inside the existingtry/finally, so the connection is still closed and untracked on every path, andclose(server)still waits for the task.WebSockets.upgradeinsideHTTP.listen!is unaffected: there the HTTP server's own error path logs handler errors.🤖 Generated with Claude Code