| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
…ts with FastAPI >= 0.137 FastAPI 0.137 changed include_router() to preserve a router tree instead of flattening routes. This causes get_request_handler() to be called on every request rather than once at registration. patch_get_request_handler() mutates dependant.call in-place, accumulating one _sentry_call wrapper per request. After ~987 requests Python's 1000-frame recursion limit is hit and the sync endpoint returns 500 permanently. Fix: add a _sentry_is_patched sentinel to _sentry_call so subsequent calls to the patched factory skip re-wrapping an already-patched dependant. Fixes getsentry#6568 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…0.137 (getsentry#6569) Add a marker to the `_sentry_call` function used to patch `dependant.call`. Avoid patching an already-patched synchronous handler by checking the marker. Duplicate wrapping occurred starting with FastAPI version 0.137. In that release, `include_router()` preserves a router tree instead of flattening routes, causing `get_request_handler()` to be called on every request (the wrapper count grew by 1 per request). Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Fixes #6568
What
patch_get_request_handler() wraps dependant.call in a _sentry_call closure and writes it back to the shared dependant object. In FastAPI ≤ 0.136 this was called once per route at registration time, so one wrapper was applied and never repeated. In FastAPI 0.137, include_router() preserves a router tree instead of flattening routes, causing get_request_handler() to be called on every request — so the wrapper count grows by 1 per request, until Python's 1000-frame recursion limit is hit at ~987 requests and the endpoint returns 500 permanently.
Only def (sync) endpoints are affected. async def endpoints go through _sentry_app, not _sentry_call, and are unaffected.
Why the root cause is correct
Test proves it
test_sync_endpoint_does_not_crash_after_many_requests sends 1,000 requests to a sync endpoint registered via include_router() and asserts all return 200. With the bug it fails at request 987; with the fix all 1,000 pass.
Note: the test takes ~75 seconds because it sends 1,000 real requests through TestClient. Happy to discuss a faster approach if the team prefers (e.g. inspecting dependant.call directly, or parameterising the request count).
Would not reccommed to merge this test as-is
Additionally, the diagnosis was confirmed by local reproduction before filing the issue:
How
Add a _sentry_is_patched = True sentinel attribute to _sentry_call after wrapping, and check for it before wrapping. If dependant.call is already patched, skip — the _sentry_call still executes on every request (thread/profiling context updates still happen), it just isn't re-wrapped.