Skip to content

Close all outstanding responses on client close - #322

Closed
dobrovolsky wants to merge 1 commit into
encode:masterfrom
dobrovolsky:close_all
Closed

dobrovolsky wants to merge 1 commit into
encode:masterfrom
dobrovolsky:close_all

Conversation

@dobrovolsky

Copy link
Copy Markdown
Contributor

related to #35

with Client() as client:
    response = client.get(..., stream=True)
response.read()  # This should raise an error.

@sethmlarson

Copy link
Copy Markdown
Contributor

Thanks for opening this @dobrovolsky! :)

@florimondmanca florimondmanca left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, sorry that we seem to have let this slip under our radar!

Overall this is a great starting point, thank you! That said, we still need to make sure connections are properly closed so that the RemoteProtocolError does not happen in the first place. I've left a comment with various hints on how this could be implemented. Please let me know if you'd like to take it on!


assert response.status_code == 200
with pytest.raises(RemoteProtocolError):
response.read()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should not let an h11 exception bubble up to our users; we need to raise an HTTPX-specific exception here. I believe ResponseClosed is the most adequate.

This made me realize that we are not force-closing responses yet here on client exit. You can see this by turning on HTTPX_DEBUG and seeing receive_event NEED_DATA log lines because the response object is still trying to receive response data, and that is because we did not call .close() on it to send a ResponseClosed event to h11.

I guess implementing response closing on client exit involves some form of storing "pending responses" on the client. We'd add the response there in the .request() methods, remove it when the response's on_close() callback is normally called, and iterate over it in client's __exit__() or __aexit__() to close any pending responses.

Would you like to look into this?

@lovelydinosaur

Copy link
Copy Markdown
Member

Thanks for having put a bunch of time into this.
As it happens, it's now obsoleted by our more tightly bounded stream() API, which ensures that connections can only be held open within a stream() context block.

Kludex referenced this pull request in pydantic/httpx2 May 11, 2026
Bumps [black](https://github.com/psf/black) from 20.8b1 to 21.4b2.
- [Release notes](https://github.com/psf/black/releases)
- [Changelog](https://github.com/psf/black/blob/master/CHANGES.md)
- [Commits](https://github.com/psf/black/commits)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Tom Christie <tom@tomchristie.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants