Repository navigation
feat: capture Litestar errors without LitestarIntegration while Sentry tracing is off - #361
Merged
Merged
Conversation
…y tracing is off LitestarConfig.sentry_lean_error_capture defaults to None, which turns lean capture on while no Sentry tracing option is set. lite-bootstrap then disables LitestarIntegration and reports request errors through its own middleware and after_exception hook, with request data gated by data_collection. SentryInstrument is generic over its config and builds init kwargs in _build_init_params, so framework instruments can extend them.
lesnik512
added a commit
that referenced
this pull request
Oct 28, 2026
…tracing is off (#362) * Report FastAPI and FastMCP errors without StarletteIntegration while tracing is off While Sentry tracing is off, FastAPIBootstrapper and FastMcpBootstrapper disable sentry-sdk's StarletteIntegration (and FastApiIntegration on FastAPI) and report request errors through a pure-ASGI middleware instead, with the same sentry_lean_error_capture rule Litestar got in #361. The rule now lives in SentryLeanCaptureConfig, shared by all three configs. Closes #341. * Stop the integration reset fixture from re-patching Starlette in every test Clearing sentry-sdk's processed-integrations registry before each test made StarletteIntegration.setup_once run again for every bootstrap, and each run wraps Starlette.__call__ once more. By the end of the suite 126 wrappers were stacked, enough to overflow the stack on Python 3.11 in CI. Once an integration has been set up, the fixture now replaces its setup_once with a no-op, so the registries still read as a fresh process without patching twice. * Keep the exploding test handler from failing a later test's logging shutdown test_teardown_removes_filters_even_when_a_handler_close_fails added a handler whose close always raised and left it on the root logger. Its exception kept it alive until the cyclic garbage collector ran, so whether Litestar's dictConfig in a later test closed it again, and failed, depended on GC timing. The handler now raises on its first close only, and the test detaches it.
This was referenced Oct 28, 2026
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.
Closes #307.
While Sentry tracing is off, lite-bootstrap now reports Litestar request errors itself, without sentry-sdk's
LitestarIntegration. With tracing off, the integration still builds and discards a transaction on every request. On 3.0 it also records a real span when the request carries a sampledsentry-trace.This is the first of three lean-capture PRs. #341 (FastAPI, FastMCP) reuses the shared pieces here, and #313 changes
auto_enabling_integrationson top of both.Changes
LitestarConfig.sentry_lean_error_capture: bool | None = None. The value is resolved byis_sentry_lean_error_capture_on():Noneturns lean capture on whenSentryConfig.is_sentry_tracing_requested()is false andsentry_integrationsholds noLitestarIntegration.Trueforces it, and warns as feat: add sentry_lean_error_capture for Litestar #304 did when tracing is on or aLitestarIntegrationis supplied.Falsekeeps the integration.SentryConfig.is_sentry_tracing_requested(). True whensentry_traces_sample_rate, ortraces_sample_rate,traces_samplerorenable_tracinginsentry_additional_params, is notNone. Capture Sentry errors without the Starlette integration when Sentry tracing is off (FastAPI, FastMCP) #341 needs the same rule.SentryInstrumentis generic over its config and builds its kwargs in_build_init_params().LitestarSentryInstrumentappendsLitestarIntegrationtodisabled_integrations.LitestarSentryCaptureMiddlewareandcapture_litestar_exception_after_handlingare ported, with these changes:sessions.track_sessionis called directly. Theauto_session_tracking_scopefallback and theis_sentry_litestar_integration_installedprobe are gone, as the issue asked.ignore_logger_for_eventson 3.x andignore_loggeron 2.x, like the integration on each major.event_from_exceptiongetsclient_optionson 2.x only, because 3.x dropped the parameter._get_request_datafromsentry_sdk.integrations._asgi_commonsupplies the method, URL, query string, headers, and the client address whenuser_infois on. It runs the headers and query string through thedata_collectiondenylists._apply_key_value_collection_filtering, asLitestarIntegrationdoes.retrieve_user_from_scope, only whenuser_infois on.http_bodiesincludes"incoming_request"and the handler already read it. It is taken from Litestar'sScopeState: JSON first, then form, then the raw body.scripts/floor_smoke.py. The Litestar target sends one failing request through the default path. I ran the litestar floors locally on 3.11 and 3.14 (sentry-sdk 2.70.0, litestar 2.22.0).Departures from the issue
_get_request_data,_RootPathInPathand_apply_key_value_collection_filteringare underscored. feat: add sentry_lean_error_capture for Litestar #304 reimplemented the header masking by hand. Withdata_collectionalways set, that would have meant copying sentry-sdk's denylist matching as well, and it would drift. Thesentry-majorsjob runs the request-data tests on both majors, so a rename fails CI.LitestarIntegrationkeeps the integration underNone. feat: add sentry_lean_error_capture for Litestar #304 warned and dropped it, which was fine for an opt-in. With lean capture as the default, the same rule would silently override a user'sLitestarIntegration(failed_request_status_codes=...).enable_tracingcounts as tracing. It is a 2.x option that turns tracing on, and it raisesTypeErroron 3.x.content_length. The integration readsscope["_body"], which Litestar 2.25 never sets, so it always reports 0.performance.mdfrom Benchmark docs: add Litestar, FastStream and FastMCP tables, the unsampled-OTel floor and the macOS caveat #335, which hasn't landed. The in-process rerun is below.Tests
tests/test_litestar_sentry_capture.pywas written first. #304's tests are ported, and these are new:test_lean_capture_is_the_default_while_tracing_is_offbuilds aLitestarConfigwith onlysentry_dsnset. On main it failed with'litestar' inthe active integrations.sentry_traces_sample_rate,traces_sample_rate,traces_sampler) keep the integration, as does a suppliedLitestarIntegration.cookiesisoff. The user and client address appear only withuser_info. The body cases: JSON, form and raw bodies read by the handler, a body the handler never read, andhttp_bodies=[].service_debugoff and on, on both majors.test_litestar_bootstrapper_runs_without_sentry_sdkreloads the Litestar module with sentry-sdk missing. It caught a module-levelIS_SENTRY_SDK_2import that failed without sentry-sdk installed.The fixture that resets
litestarin sentry-sdk's process-wide registries now clears it from_processed_integrationstoo. Otherwise an earlier lean bootstrap leaves the integration "processed but not installed", and a later test cannot turn it on. Re-enabling it runssetup_onceagain and patchesHTTPRoute.handlea second time. So the tests that use the integration path check only that it is active, not how many events it sends.The full suite passes at 100% on sentry-sdk 2.73.0 and 3.0.0b2, and
typasses against both.just lint,just adr-check,just docs-buildand lychee pass.Measurement
These are in-process numbers from
benchmarks/frameworks/bench.py litestar ... --repeat 2on an M2 Mac (CPython 3.14.7, litestar 2.25.0), in µs per request over bare Litestar. The new scenarios are inlitestar_suite.py.sentry(lean, the new default)sentry_sampled_tracesentry_integration(sentry_lean_error_capture=False)sentry_integration_sampled_tracesentry_nointegration, which disables the integration and adds nothing else, measured +7.9 on both majors, so the lean middleware itself costs almost nothing.Docs
docs/integrations/litestar.md: a new Sentry section covering the rule, what is reported, what request data is attached, and the numbers.configuration.md: a bullet for the field.performance.md: the "Sentry costs more on Litestar" paragraph now describes the 2.0 default.benchmarks/README.md: the pre-2.0 Litestar rows are relabelled "1.x defaults", and the rerun table is added.Breaking changes
These apply to Litestar services with a
sentry_dsnand no tracing option.exception_handlersentry turns into a 4xx response is no longer reported.LitestarIntegrationreports it.http_bodiesallows it. The integration read it before the handler ran.Set
sentry_lean_error_capture=Falseto keep the integration.