Skip to content

Translate backend EOF errors into ProxyError - #53

Open
Quinnod345 wants to merge 1 commit into
romis2012:masterfrom
Quinnod345:fix/backend-eof-errors
Open

Quinnod345 wants to merge 1 commit into
romis2012:masterfrom
Quinnod345:fix/backend-eof-errors

Conversation

@Quinnod345

Copy link
Copy Markdown

AnyIO v1 catches the stdlib incomplete-read exception, but its stream raises the package exception. Asyncio v2 has the reverse mismatch. A peer closing during negotiation therefore bypasses the intended ProxyError conversion.

Catch each stream's actual EOF type. Keep AnyIO's existing shielded cleanup behavior when moving EOF into its specific handler. The regression uses the public proxy APIs with both AnyIO backends and asyncio v2. It covers truncated replies, protocol errors, successful tunnels and cancellation.

Local validation against upstream 8d054e5855e354735b95f2004d9fe8242920e261:

  • The same final regression has 14 failures and 12 passing controls on upstream. Correcting only the exception imports leaves 2 close-cancellation failures and 24 passes. The complete fix passes all 26 cases.
  • All 429 project tests pass on macOS with CPython 3.14.7, AnyIO 4.16.0 and Trio 0.35.0. That run used owned loopback fixtures with ephemeral ports and runtime URL data.
  • Ruff and formatting pass. Focused Mypy passes 60 files. Full Mypy reports three errors in unchanged test helpers; pristine upstream has the same diagnostics in this environment.

Other Python versions, operating systems and hosted CI were not run locally. The close-cancellation regression uses an owned asynchronous test stream; it does not demonstrate a native transport leak.

I maintain Ponder. Its review flagged the mismatched EOF handlers and helped check cleanup preservation. I implemented the patch and ran the checks above.

Catch the actual incomplete-read types produced by AnyIO v1 and asyncio
v2. Preserve AnyIO's shielded EOF cleanup while using its specific handler.

Add truncation, protocol-error, success and cancellation regressions.
The identical 26 cases fail 14 times on upstream and pass with this fix.
Owned-loopback project validation passes 429 tests on macOS Python 3.14;
full Mypy retains three unchanged upstream test-helper diagnostics.
@romis2012

romis2012 commented Nov 12, 2026 •

Copy link
Copy Markdown
Owner

In asyncio v2 we should handle python_socks._errors.IncompleteReadError (not asyncio.IncompleteReadError) for consistency.
At the same time we should catch asyncio.IncompleteReadError and raise python_socks._errors.IncompleteReadError in python_socks.async_.asyncio.v2._stream.AsyncioSocketStream.read_exactly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants