-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Release HTTP response before raising status exception #3365
Release HTTP response before raising status exception #3365
Conversation
We need regression tests. And if you cannot reproduce an issue within aiohttp, is it a real bug then? I'd like more details on this before proceeding. Maybe togather we could come up with a solution... |
Codecov Report
@@ Coverage Diff @@
## master #3365 +/- ##
=======================================
Coverage 97.96% 97.96%
=======================================
Files 44 44
Lines 8413 8413
Branches 1374 1374
=======================================
Hits 8242 8242
Misses 72 72
Partials 99 99 Continue to review full report at Codecov.
|
Thank you @webknjaz for checking in. I can confirm this issue is real. However, the only times I have been able to confirm this issue with a remote host and a large response body. Come to think, it might not actually be a limitation of aiohttp's server, but a problem with local networking. I haven't tried to run an aiohttp server on a remote system yet to see if I could reproduce the issue. It might be that local networking is the issue. And by issue, I mean I'm not sure whether either
Question: Does Python or one of the lower level components of aiohttp expose information about TCP connection statuses? If so, that would make testing the connection states a lot easier. This was a script I used to test a big server response: server.py from aiohttp import web, ClientSession
async def body(request):
client = ClientSession()
async with client.get('https://en.wikipedia.org/wiki/Main_Page#/media/File:Lewis_Carroll_-_Henry_Holiday_-_Hunting_of_the_Snark_-_Plate_9.jpg') as response:
body = await response.read()
await client.close()
return web.Response(body=str(body)+str(body)+str(body), status=404)
app = web.Application()
app.add_routes([web.get('/', body)])
web.run_app(app) |
Better fix is calling |
No problem, I've updated the PR with a check on |
Thanks @HansAdema ! |
Hi guys, Sorry for necroing, but after quite some time we've upgraded to recent version of aiohttp and lots of our error handling code stopped working due to the change introduced in this PR. Here example of the code we use for error handling: async with aiohttp.ClientSession() as s:
res = await s.get("https://google.com/not-such-thing")
try:
res.raise_for_status()
except aiohttp.ClientResponseError as err:
print("Failed. The error body:")
print(await res.text()) Awaiting for If I understand right, the reason for the fix was to prevent connection leaking if exception was raised, right? Anyhow, for us it is quite a big breaking change. What would be your recommendation? Switch to manual status code parsing? Namely: async with aiohttp.ClientSession() as s:
res = await s.get("https://google.com/not-such-thing")
if 400 <= res.status:
print("Failed. The error body:")
print(await res.text()) Thank you. |
Ran into this as well. In general it's annoying that the ClientResponseError doesn't include body. But now the simple workaround doesn't exist. You have to implement your own raise_for_status method. |
I'm sorry, guys, for the design mistake made years ago. If you need a response body the manual status code parsing is maybe the best option available (currently Providing a response body as an attribute of |
I don't understand the need for the close in method thou. Either there is a context manager or you need be prepared for manual closing in some finally clause right. I suppose it would be an easy case to miss though. Work around isn't too hard though. |
Generally speaking, you don't know at the exception catch point if the response was closed or not. |
I'll second asvelov here. Though this change caught us off guard and we had to fix thing on the spot, eventually I think it brings clarity wrt resource management. |
What do these changes do?
A bugfix for issue #3364 - it releases the HTTP response before the ClientResponse exception is thrown.
Are there changes in behavior for the user?
If there is some way to get the HTTP response from a ClientResponseException (which, AFAIK, isn't possible), the response would be closed already.
Beyond that, no behavioral changes except for that connections are closed properly.
Related issue number
#3364
Checklist
CONTRIBUTORS.txt
CHANGES
folder<issue_id>.<type>
for example (588.bugfix)issue_id
change it to the pr id after creating the pr.feature
: Signifying a new feature..bugfix
: Signifying a bug fix..doc
: Signifying a documentation improvement..removal
: Signifying a deprecation or removal of public API..misc
: A ticket has been closed, but it is not of interest to users.