fix(websocket): Raise IOException on closed connection instead of returning b""#1213
Merged
fix(websocket): Raise IOException on closed connection instead of returning b""#1213
Conversation
…urning b"" Fixes #1212 - WebSocket read() now raises IOException when connection is closed, allowing read_exactly() to immediately detect closure instead of retrying 100 times on empty bytes - Yamux send_window_update() gracefully handles connection closure errors during window updates (data was already read successfully) - Improved _extract_close_info() fallback for non-standard exceptions - Added exception chaining (from e) in write() for better tracebacks - Comprehensive test suite for closure handling scenarios Co-authored-by: Cursor <cursoragent@cursor.com>
…ectionClosedError Add ConnectionClosedError(IOException) with structured close_code, close_reason, and transport attributes. The WebSocket transport now raises this typed exception instead of a plain IOException with the close info buried in the message string. Yamux catches it by type (`except ConnectionClosedError`) instead of parsing `str(e).lower()` for closure keywords — eliminating a fragile pattern that would silently break if anyone changed an error message. A string-matching fallback is retained for transports that don't yet raise ConnectionClosedError (e.g. TCP RawConnError). Co-authored-by: Cursor <cursoragent@cursor.com>
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.
Summary
Fixes #1212
read()now raisesIOExceptionwhen the connection is closed, instead of returningb"". This allowsread_exactly()to immediately detect closure instead of retrying up to 100 times on empty bytes.send_window_update()gracefully handles connection closure errors during window updates — when the peer closes the connection between reading data and sending the window update (common with Nim, JVM, rust-v0.53), the error is logged at debug level instead of crashing, since the data was already read successfully._extract_close_info()fallback to handle mock exceptions and non-standard exception types withcode/reasondirectly on the exception object.read()for connection closure exceptions missed by inner handlers.from e) inwrite()for better tracebacks.Background
This is a fresh, minimal implementation based on current
main. The original PR #1083 (addressing issue #1082) was 335 commits behind main with 3 merge conflicts, and ~50% of its changes had already landed via PR #964 and PR #1114. This PR carries forward only the remaining unfixed bugs.Test plan
make lint— all checks passmake typecheck— mypy and pyrefly passmake test— 2091 passed, 16 skipped, 0 failuresmake linux-docs— docs build + 109 doctests passsend_window_update()error handling (7 tests)1212.bugfix.rstincludedMade with Cursor