Recursively extract HTTP errors from nested ExceptionGroups#3556
Open
mshsheikh wants to merge 1 commit into
Open
Recursively extract HTTP errors from nested ExceptionGroups#3556mshsheikh wants to merge 1 commit into
mshsheikh wants to merge 1 commit into
Conversation
This PR improves how the code finds HTTP-related errors inside nested exception groups.
Right now, `_extract_http_error_from_exception()` only checks the first level of `BaseExceptionGroup.exceptions`. That works when the HTTP error is directly inside the group, but it fails when the error is wrapped inside another `ExceptionGroup`. In async code, this can happen when multiple tasks fail at the same time and the errors are grouped together more than once.
With this change, the method now checks exception groups recursively. That means it keeps looking inside nested groups until it finds a matching HTTP error or confirms that none is present. This makes error detection more reliable and helps the code report the real network problem instead of missing it.
This is a small but important reliability fix. It does not change the normal success path. It only improves how nested errors are handled when failures happen.
### Before
```python
def _extract_http_error_from_exception(self, e: BaseException) -> Exception | None:
"""Extract HTTP error from exception or ExceptionGroup."""
if isinstance(e, httpx.HTTPStatusError | httpx.ConnectError | httpx.TimeoutException):
return e
# Check if it's an ExceptionGroup containing HTTP errors
if isinstance(e, BaseExceptionGroup):
for exc in e.exceptions:
if isinstance(
exc, httpx.HTTPStatusError | httpx.ConnectError | httpx.TimeoutException
):
return exc
return None
```
### After
```python
def _extract_http_error_from_exception(self, e: BaseException) -> Exception | None:
"""Extract HTTP error from exception or ExceptionGroup recursively."""
if isinstance(e, httpx.HTTPStatusError | httpx.ConnectError | httpx.TimeoutException):
return e
if isinstance(e, BaseExceptionGroup):
for exc in e.exceptions:
result = self._extract_http_error_from_exception(exc)
if result is not None:
return result
return None
```
### Why this matters
* It catches HTTP errors even when they are nested inside multiple exception groups.
* It improves error reporting during async cleanup and grouped task failures.
* It helps the retry and user error logic work with the actual root cause.
* It makes the method more robust in real async failure cases.
### Impact
This change is safe and low risk. It only affects exception handling when failures occur. Normal requests and successful flows are unchanged.
### Testing idea
A good test would create a nested `ExceptionGroup` that contains an `httpx.ConnectError` or `httpx.TimeoutException` several levels deep, then verify that the method still finds and returns the correct HTTP error.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR improves how the code finds HTTP-related errors inside nested exception groups.
Right now,
_extract_http_error_from_exception()only checks the first level ofBaseExceptionGroup.exceptions. That works when the HTTP error is directly inside the group, but it fails when the error is wrapped inside anotherExceptionGroup. In async code, this can happen when multiple tasks fail at the same time and the errors are grouped together more than once.With this change, the method now checks exception groups recursively. That means it keeps looking inside nested groups until it finds a matching HTTP error or confirms that none is present. This makes error detection more reliable and helps the code report the real network problem instead of missing it.
This is a small but important reliability fix. It does not change the normal success path. It only improves how nested errors are handled when failures happen.
Before
After
Why this matters
Impact
This change is safe and low risk. It only affects exception handling when failures occur. Normal requests and successful flows are unchanged.
Testing idea
A good test would create a nested
ExceptionGroupthat contains anhttpx.ConnectErrororhttpx.TimeoutExceptionseveral levels deep, then verify that the method still finds and returns the correct HTTP error.