fix: Add cycle detection to exceptions_from_error#5880
Open
ericapisani wants to merge 4 commits intomasterfrom
Open
fix: Add cycle detection to exceptions_from_error#5880ericapisani wants to merge 4 commits intomasterfrom
ericapisani wants to merge 4 commits intomasterfrom
Conversation
When using FastAPI with multiple BaseHTTPMiddleware instances, anyio wraps exceptions in ExceptionGroups. When Starlette unpacks and reraises these, it creates cyclic references (ExceptionGroup -> ValueError -> __cause__ -> ExceptionGroup) that cause infinite recursion in exceptions_from_error(), silently dropping the event. Track seen exception object ids during recursive walks through __cause__, __context__, and ExceptionGroup.exceptions to break cycles. Fixes GH-5025 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace test_cyclic_exception_group_context with test_exceptiongroup_starlette_collapse that simulates the actual collapse_excgroups() pattern from Starlette. This provides a more realistic regression test for the cycle detection in exceptions_from_error() by reproducing the exact __context__ cycle that occurs in production with FastAPI and multiple BaseHTTPMiddleware instances. Remove the now-redundant synthetic __context__ cycle test since the new test covers the same code path with a more representative scenario. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Contributor
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Langchain
Bug Fixes 🐛Ci
Openai
Other
Internal Changes 🔧Langchain
Other
Other
🤖 This preview updates automatically when you update the PR. |
Contributor
Codecov Results 📊✅ 13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 7.48s All tests are passing successfully. ❌ Patch coverage is 0.00%. Project has 14421 uncovered lines. Files with missing lines (1)
Generated by Codecov Action |
Member
Author
|
bugbot run |
Type seen_exceptions as Optional[list[BaseException]] instead of Optional[list] and split the None checks for seen_exceptions and seen_exception_ids so each parameter is independently initialized. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
exceptions_from_error()to prevent infinite recursion when exception chains contain cyclesBaseHTTPMiddlewareinstances cause Starlette'scollapse_excgroups()to create cyclic__context__references (ExceptionGroup → inner exception →__context__→ ExceptionGroup)RecursionErrorTest plan
test_exceptiongroup_starlette_collapse— realistic reproduction of the Starlettecollapse_excgroups()pattern with exact expected exception valuestest_cyclic_exception_group_cause— verifies cycle detection works for__cause__chainstest_deeply_nested_cyclic_exception_group— verifies cycle detection across multiple nested ExceptionGroupsFixes #5025 and PY-1949
🤖 Generated with Claude Code