-
-
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
aiohttp does not try connecting to multiple IPs if first connect times out #7342
Comments
Just noticed that it's an |
Would be great if you could create a regression test in a PR for this. Fix looks pretty simple, just need to catch We probably also need to adjust the default timeout to make sure this works by default (currently, only total timeout is specified, which means it will wait until the end of the timeout on the first attempt and then cancel the whole client request; sock_connect needs to be set to something smaller). |
Ah, that would explain why my test saw an uncaught I can look at creating a PR; I'm just still unsure what the desired behavior is - i.e. what various errors should fail over to the next host in the list, and which should be raised to the caller. |
I think you just misread the traceback. The CancelledError is triggered by the timeout code, which changes it to a TimeoutError, then at a later point back in the Client code that becomes a ServerTimeoutError. At the point of that loop, it is a TimeoutError that we need to catch (if there's a different CancelledError, then the task is being asked to cancel, so we certainly shouldn't ignore it). |
In a previous test, I was using the I guess it's a bit surprising that changing client code with an innocent-looking change like this: - timeout = aiohttp.ClientTimeout(total=30, connect=5)
+ timeout = aiohttp.ClientTimeout(total=30, sock_connect=5) changes the type of the exception raised on connection timeout, but I can confirm that the loop works as expected when modified to catch |
Hmm, no, I still see I'm not sure it makes sense to retry here, and not too sure what the best approach is, maybe we just need to tweak the documentation to highlight the difference. |
Describe the bug
The ability to try connecting all addresses in a DNS record was added in #2447, some time ago. However, when using aiohttp in a static IP setup with entries in
/etc/hosts
, if the connection to the first address for a hostname times out, aiohttp gives up and does not try connecting to other hosts. I confirmed this by adding aprint
statement here, in the loop over hosts, before the connection attempt; only the first address was printed before theServerTimeoutError
exception was raised.This appears to be because of a too-narrow
except
block, which catches onlyClientConnectorError
- but the error raised on connection timeout isServerTimeoutError
. It's possible that thisexcept
block should useClientConnectionError
instead, which isServerTimeoutError
's grandparent class (viaServerConnectionError
). However, I don't know whether that's correct or not in the larger context.To Reproduce
Note: I did my testing with https, since I already had a certificate for a static IP hostname set up; the steps and script could probably be adjusted to use http instead, which would make the repro simpler (and would not affect its validity).
python:3.11.4
image):ips
array to contain two real IP addresses:host
string to the hostname matching a certificate that your https server above is usingaiohttp Version
multidict Version
yarl Version
OS
Related component
Client
Additional context
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: