Skip to content

Conversation

samm81
Copy link
Contributor

@samm81 samm81 commented Oct 4, 2025

I believe this solves #1126

  • http: retry safe DAV methods on transient aiohttp disconnects
  • cli: gather with return_exceptions to allow in-flight backoffs to finish
  • Retry ServerDisconnectedError/ServerTimeoutError/ClientConnectionError/asyncio.TimeoutError for GET/HEAD/OPTIONS/PROPFIND/REPORT
  • Keep original rate-limit handling (429, Google 403 usageLimits)
  • In CLI, avoid cancelling sibling tasks so per-request backoff can complete; re-raise first failure after all tasks finish

samm81 added 2 commits October 4, 2025 23:17
…ather with return_exceptions to allow in-flight backoffs to finish

- Retry ServerDisconnectedError/ServerTimeoutError/ClientConnectionError/asyncio.TimeoutError for GET/HEAD/OPTIONS/PROPFIND/REPORT
- Keep original rate-limit handling (429, Google 403 usageLimits)
- In CLI, avoid cancelling sibling tasks so per-request backoff can complete; re-raise first failure after all tasks finish
@WhyNotHugo
Copy link
Member

Rebased with minor tweaks (mostly formatting).

@WhyNotHugo
Copy link
Member

Seems to mess up some TLS tests:

FAILED tests/system/utils/test_main.py::test_request_ssl - vdirsyncer.http.TransientNetworkError: Cannot connect to host self-signed.badssl.com:443 ssl:True [SSLCertVerificationError: (1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate (_ssl.c:1032)')]
FAILED tests/system/utils/test_main.py::test_request_ssl_leaf_fingerprint[SHA256] - vdirsyncer.http.TransientNetworkError: (b'\x04d\x04jh\x15\xd7V\x8a\xf4\xc0w\\F\x82\xaa\x08\x0eK\xdbx\xbb\xdf\x15y3\xd3\x8e\x84\x14Ic', b'6\x94AH\xe8=3\x97Q\xfd\xbb\x87\xbd\xb4\xe0\x80\xaa(d\xc5w\x0cO\xa8e}Q\x86\xa6@F@', '127.0.0.1', 39657)

samm81 added 2 commits October 9, 2025 15:57
- `ClientConnectionError` in `aiohttp` can wrap SSL handshake and
  certificate verification errors
- Retrying those hides the real cause and produced
  `TransientNetworkError` instead of the expected certificate error
- Removing `ClientConnectionError` from the transient list lets SSL
  errors surface correctly
@samm81
Copy link
Contributor Author

samm81 commented Oct 9, 2025

@WhyNotHugo tests now pass :)

@WhyNotHugo WhyNotHugo merged commit b124ce8 into pimutils:main Oct 9, 2025
5 checks passed
Comment on lines 149 to +157

await asyncio.gather(*tasks)
# `return_exceptions=True` ensures that the event loop lives long enough for
# backoffs to be able to finish
gathered = await asyncio.gather(*tasks, return_exceptions=True)
# but now we need to manually check for and propogate a single failure after
# allowing all tasks to finish in order to keep exit status non-zero
failures = [e for e in gathered if isinstance(e, BaseException)]
if failures:
raise failures[0]
Copy link
Member

Choose a reason for hiding this comment

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

I just noticed that this is outside the async with aiohttp.TCPConnector(limit_per_host=16) as conn: block.

The connector will be closed by the time this block is reached, so it will likely still lead to #1126.

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