sentry-sdk 0.7.5__py2.py3-none-any.whl → 2.46.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. sentry_sdk/__init__.py +48 -30
  2. sentry_sdk/_compat.py +74 -61
  3. sentry_sdk/_init_implementation.py +84 -0
  4. sentry_sdk/_log_batcher.py +172 -0
  5. sentry_sdk/_lru_cache.py +47 -0
  6. sentry_sdk/_metrics_batcher.py +167 -0
  7. sentry_sdk/_queue.py +289 -0
  8. sentry_sdk/_types.py +338 -0
  9. sentry_sdk/_werkzeug.py +98 -0
  10. sentry_sdk/ai/__init__.py +7 -0
  11. sentry_sdk/ai/monitoring.py +137 -0
  12. sentry_sdk/ai/utils.py +144 -0
  13. sentry_sdk/api.py +496 -80
  14. sentry_sdk/attachments.py +75 -0
  15. sentry_sdk/client.py +1023 -103
  16. sentry_sdk/consts.py +1438 -66
  17. sentry_sdk/crons/__init__.py +10 -0
  18. sentry_sdk/crons/api.py +62 -0
  19. sentry_sdk/crons/consts.py +4 -0
  20. sentry_sdk/crons/decorator.py +135 -0
  21. sentry_sdk/debug.py +15 -14
  22. sentry_sdk/envelope.py +369 -0
  23. sentry_sdk/feature_flags.py +71 -0
  24. sentry_sdk/hub.py +611 -280
  25. sentry_sdk/integrations/__init__.py +276 -49
  26. sentry_sdk/integrations/_asgi_common.py +108 -0
  27. sentry_sdk/integrations/_wsgi_common.py +180 -44
  28. sentry_sdk/integrations/aiohttp.py +291 -42
  29. sentry_sdk/integrations/anthropic.py +439 -0
  30. sentry_sdk/integrations/argv.py +9 -8
  31. sentry_sdk/integrations/ariadne.py +161 -0
  32. sentry_sdk/integrations/arq.py +247 -0
  33. sentry_sdk/integrations/asgi.py +341 -0
  34. sentry_sdk/integrations/asyncio.py +144 -0
  35. sentry_sdk/integrations/asyncpg.py +208 -0
  36. sentry_sdk/integrations/atexit.py +17 -10
  37. sentry_sdk/integrations/aws_lambda.py +377 -62
  38. sentry_sdk/integrations/beam.py +176 -0
  39. sentry_sdk/integrations/boto3.py +137 -0
  40. sentry_sdk/integrations/bottle.py +221 -0
  41. sentry_sdk/integrations/celery/__init__.py +529 -0
  42. sentry_sdk/integrations/celery/beat.py +293 -0
  43. sentry_sdk/integrations/celery/utils.py +43 -0
  44. sentry_sdk/integrations/chalice.py +134 -0
  45. sentry_sdk/integrations/clickhouse_driver.py +177 -0
  46. sentry_sdk/integrations/cloud_resource_context.py +280 -0
  47. sentry_sdk/integrations/cohere.py +274 -0
  48. sentry_sdk/integrations/dedupe.py +48 -14
  49. sentry_sdk/integrations/django/__init__.py +584 -191
  50. sentry_sdk/integrations/django/asgi.py +245 -0
  51. sentry_sdk/integrations/django/caching.py +204 -0
  52. sentry_sdk/integrations/django/middleware.py +187 -0
  53. sentry_sdk/integrations/django/signals_handlers.py +91 -0
  54. sentry_sdk/integrations/django/templates.py +79 -5
  55. sentry_sdk/integrations/django/transactions.py +49 -22
  56. sentry_sdk/integrations/django/views.py +96 -0
  57. sentry_sdk/integrations/dramatiq.py +226 -0
  58. sentry_sdk/integrations/excepthook.py +50 -13
  59. sentry_sdk/integrations/executing.py +67 -0
  60. sentry_sdk/integrations/falcon.py +272 -0
  61. sentry_sdk/integrations/fastapi.py +141 -0
  62. sentry_sdk/integrations/flask.py +142 -88
  63. sentry_sdk/integrations/gcp.py +239 -0
  64. sentry_sdk/integrations/gnu_backtrace.py +99 -0
  65. sentry_sdk/integrations/google_genai/__init__.py +301 -0
  66. sentry_sdk/integrations/google_genai/consts.py +16 -0
  67. sentry_sdk/integrations/google_genai/streaming.py +155 -0
  68. sentry_sdk/integrations/google_genai/utils.py +576 -0
  69. sentry_sdk/integrations/gql.py +162 -0
  70. sentry_sdk/integrations/graphene.py +151 -0
  71. sentry_sdk/integrations/grpc/__init__.py +168 -0
  72. sentry_sdk/integrations/grpc/aio/__init__.py +7 -0
  73. sentry_sdk/integrations/grpc/aio/client.py +95 -0
  74. sentry_sdk/integrations/grpc/aio/server.py +100 -0
  75. sentry_sdk/integrations/grpc/client.py +91 -0
  76. sentry_sdk/integrations/grpc/consts.py +1 -0
  77. sentry_sdk/integrations/grpc/server.py +66 -0
  78. sentry_sdk/integrations/httpx.py +178 -0
  79. sentry_sdk/integrations/huey.py +174 -0
  80. sentry_sdk/integrations/huggingface_hub.py +378 -0
  81. sentry_sdk/integrations/langchain.py +1132 -0
  82. sentry_sdk/integrations/langgraph.py +337 -0
  83. sentry_sdk/integrations/launchdarkly.py +61 -0
  84. sentry_sdk/integrations/litellm.py +287 -0
  85. sentry_sdk/integrations/litestar.py +315 -0
  86. sentry_sdk/integrations/logging.py +307 -96
  87. sentry_sdk/integrations/loguru.py +213 -0
  88. sentry_sdk/integrations/mcp.py +566 -0
  89. sentry_sdk/integrations/modules.py +14 -31
  90. sentry_sdk/integrations/openai.py +725 -0
  91. sentry_sdk/integrations/openai_agents/__init__.py +61 -0
  92. sentry_sdk/integrations/openai_agents/consts.py +1 -0
  93. sentry_sdk/integrations/openai_agents/patches/__init__.py +5 -0
  94. sentry_sdk/integrations/openai_agents/patches/agent_run.py +140 -0
  95. sentry_sdk/integrations/openai_agents/patches/error_tracing.py +77 -0
  96. sentry_sdk/integrations/openai_agents/patches/models.py +50 -0
  97. sentry_sdk/integrations/openai_agents/patches/runner.py +45 -0
  98. sentry_sdk/integrations/openai_agents/patches/tools.py +77 -0
  99. sentry_sdk/integrations/openai_agents/spans/__init__.py +5 -0
  100. sentry_sdk/integrations/openai_agents/spans/agent_workflow.py +21 -0
  101. sentry_sdk/integrations/openai_agents/spans/ai_client.py +42 -0
  102. sentry_sdk/integrations/openai_agents/spans/execute_tool.py +48 -0
  103. sentry_sdk/integrations/openai_agents/spans/handoff.py +19 -0
  104. sentry_sdk/integrations/openai_agents/spans/invoke_agent.py +86 -0
  105. sentry_sdk/integrations/openai_agents/utils.py +199 -0
  106. sentry_sdk/integrations/openfeature.py +35 -0
  107. sentry_sdk/integrations/opentelemetry/__init__.py +7 -0
  108. sentry_sdk/integrations/opentelemetry/consts.py +5 -0
  109. sentry_sdk/integrations/opentelemetry/integration.py +58 -0
  110. sentry_sdk/integrations/opentelemetry/propagator.py +117 -0
  111. sentry_sdk/integrations/opentelemetry/span_processor.py +391 -0
  112. sentry_sdk/integrations/otlp.py +82 -0
  113. sentry_sdk/integrations/pure_eval.py +141 -0
  114. sentry_sdk/integrations/pydantic_ai/__init__.py +47 -0
  115. sentry_sdk/integrations/pydantic_ai/consts.py +1 -0
  116. sentry_sdk/integrations/pydantic_ai/patches/__init__.py +4 -0
  117. sentry_sdk/integrations/pydantic_ai/patches/agent_run.py +215 -0
  118. sentry_sdk/integrations/pydantic_ai/patches/graph_nodes.py +110 -0
  119. sentry_sdk/integrations/pydantic_ai/patches/model_request.py +40 -0
  120. sentry_sdk/integrations/pydantic_ai/patches/tools.py +98 -0
  121. sentry_sdk/integrations/pydantic_ai/spans/__init__.py +3 -0
  122. sentry_sdk/integrations/pydantic_ai/spans/ai_client.py +246 -0
  123. sentry_sdk/integrations/pydantic_ai/spans/execute_tool.py +49 -0
  124. sentry_sdk/integrations/pydantic_ai/spans/invoke_agent.py +112 -0
  125. sentry_sdk/integrations/pydantic_ai/utils.py +223 -0
  126. sentry_sdk/integrations/pymongo.py +214 -0
  127. sentry_sdk/integrations/pyramid.py +112 -68
  128. sentry_sdk/integrations/quart.py +237 -0
  129. sentry_sdk/integrations/ray.py +165 -0
  130. sentry_sdk/integrations/redis/__init__.py +48 -0
  131. sentry_sdk/integrations/redis/_async_common.py +116 -0
  132. sentry_sdk/integrations/redis/_sync_common.py +119 -0
  133. sentry_sdk/integrations/redis/consts.py +19 -0
  134. sentry_sdk/integrations/redis/modules/__init__.py +0 -0
  135. sentry_sdk/integrations/redis/modules/caches.py +118 -0
  136. sentry_sdk/integrations/redis/modules/queries.py +65 -0
  137. sentry_sdk/integrations/redis/rb.py +32 -0
  138. sentry_sdk/integrations/redis/redis.py +69 -0
  139. sentry_sdk/integrations/redis/redis_cluster.py +107 -0
  140. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +50 -0
  141. sentry_sdk/integrations/redis/utils.py +148 -0
  142. sentry_sdk/integrations/rq.py +95 -37
  143. sentry_sdk/integrations/rust_tracing.py +284 -0
  144. sentry_sdk/integrations/sanic.py +294 -123
  145. sentry_sdk/integrations/serverless.py +48 -19
  146. sentry_sdk/integrations/socket.py +96 -0
  147. sentry_sdk/integrations/spark/__init__.py +4 -0
  148. sentry_sdk/integrations/spark/spark_driver.py +316 -0
  149. sentry_sdk/integrations/spark/spark_worker.py +116 -0
  150. sentry_sdk/integrations/sqlalchemy.py +142 -0
  151. sentry_sdk/integrations/starlette.py +737 -0
  152. sentry_sdk/integrations/starlite.py +292 -0
  153. sentry_sdk/integrations/statsig.py +37 -0
  154. sentry_sdk/integrations/stdlib.py +235 -29
  155. sentry_sdk/integrations/strawberry.py +394 -0
  156. sentry_sdk/integrations/sys_exit.py +70 -0
  157. sentry_sdk/integrations/threading.py +158 -28
  158. sentry_sdk/integrations/tornado.py +84 -52
  159. sentry_sdk/integrations/trytond.py +50 -0
  160. sentry_sdk/integrations/typer.py +60 -0
  161. sentry_sdk/integrations/unleash.py +33 -0
  162. sentry_sdk/integrations/unraisablehook.py +53 -0
  163. sentry_sdk/integrations/wsgi.py +201 -119
  164. sentry_sdk/logger.py +96 -0
  165. sentry_sdk/metrics.py +81 -0
  166. sentry_sdk/monitor.py +120 -0
  167. sentry_sdk/profiler/__init__.py +49 -0
  168. sentry_sdk/profiler/continuous_profiler.py +730 -0
  169. sentry_sdk/profiler/transaction_profiler.py +839 -0
  170. sentry_sdk/profiler/utils.py +195 -0
  171. sentry_sdk/py.typed +0 -0
  172. sentry_sdk/scope.py +1713 -85
  173. sentry_sdk/scrubber.py +177 -0
  174. sentry_sdk/serializer.py +405 -0
  175. sentry_sdk/session.py +177 -0
  176. sentry_sdk/sessions.py +275 -0
  177. sentry_sdk/spotlight.py +242 -0
  178. sentry_sdk/tracing.py +1486 -0
  179. sentry_sdk/tracing_utils.py +1236 -0
  180. sentry_sdk/transport.py +806 -134
  181. sentry_sdk/types.py +52 -0
  182. sentry_sdk/utils.py +1625 -465
  183. sentry_sdk/worker.py +54 -25
  184. sentry_sdk-2.46.0.dist-info/METADATA +268 -0
  185. sentry_sdk-2.46.0.dist-info/RECORD +189 -0
  186. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/WHEEL +1 -1
  187. sentry_sdk-2.46.0.dist-info/entry_points.txt +2 -0
  188. sentry_sdk-2.46.0.dist-info/licenses/LICENSE +21 -0
  189. sentry_sdk/integrations/celery.py +0 -119
  190. sentry_sdk-0.7.5.dist-info/LICENSE +0 -9
  191. sentry_sdk-0.7.5.dist-info/METADATA +0 -36
  192. sentry_sdk-0.7.5.dist-info/RECORD +0 -39
  193. {sentry_sdk-0.7.5.dist-info → sentry_sdk-2.46.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,315 @@
1
+ from collections.abc import Set
2
+ from copy import deepcopy
3
+
4
+ import sentry_sdk
5
+ from sentry_sdk.consts import OP
6
+ from sentry_sdk.integrations import (
7
+ _DEFAULT_FAILED_REQUEST_STATUS_CODES,
8
+ DidNotEnable,
9
+ Integration,
10
+ )
11
+ from sentry_sdk.integrations.asgi import SentryAsgiMiddleware
12
+ from sentry_sdk.integrations.logging import ignore_logger
13
+ from sentry_sdk.scope import should_send_default_pii
14
+ from sentry_sdk.tracing import TransactionSource, SOURCE_FOR_STYLE
15
+ from sentry_sdk.utils import (
16
+ ensure_integration_enabled,
17
+ event_from_exception,
18
+ transaction_from_function,
19
+ )
20
+
21
+ try:
22
+ from litestar import Request, Litestar # type: ignore
23
+ from litestar.handlers.base import BaseRouteHandler # type: ignore
24
+ from litestar.middleware import DefineMiddleware # type: ignore
25
+ from litestar.routes.http import HTTPRoute # type: ignore
26
+ from litestar.data_extractors import ConnectionDataExtractor # type: ignore
27
+ from litestar.exceptions import HTTPException # type: ignore
28
+ except ImportError:
29
+ raise DidNotEnable("Litestar is not installed")
30
+
31
+ from typing import TYPE_CHECKING
32
+
33
+ if TYPE_CHECKING:
34
+ from typing import Any, Optional, Union
35
+ from litestar.types.asgi_types import ASGIApp # type: ignore
36
+ from litestar.types import ( # type: ignore
37
+ HTTPReceiveMessage,
38
+ HTTPScope,
39
+ Message,
40
+ Middleware,
41
+ Receive,
42
+ Scope as LitestarScope,
43
+ Send,
44
+ WebSocketReceiveMessage,
45
+ )
46
+ from litestar.middleware import MiddlewareProtocol
47
+ from sentry_sdk._types import Event, Hint
48
+
49
+ _DEFAULT_TRANSACTION_NAME = "generic Litestar request"
50
+
51
+
52
+ class LitestarIntegration(Integration):
53
+ identifier = "litestar"
54
+ origin = f"auto.http.{identifier}"
55
+
56
+ def __init__(
57
+ self,
58
+ failed_request_status_codes=_DEFAULT_FAILED_REQUEST_STATUS_CODES, # type: Set[int]
59
+ ) -> None:
60
+ self.failed_request_status_codes = failed_request_status_codes
61
+
62
+ @staticmethod
63
+ def setup_once():
64
+ # type: () -> None
65
+ patch_app_init()
66
+ patch_middlewares()
67
+ patch_http_route_handle()
68
+
69
+ # The following line follows the pattern found in other integrations such as `DjangoIntegration.setup_once`.
70
+ # The Litestar `ExceptionHandlerMiddleware.__call__` catches exceptions and does the following
71
+ # (among other things):
72
+ # 1. Logs them, some at least (such as 500s) as errors
73
+ # 2. Calls after_exception hooks
74
+ # The `LitestarIntegration`` provides an after_exception hook (see `patch_app_init` below) to create a Sentry event
75
+ # from an exception, which ends up being called during step 2 above. However, the Sentry `LoggingIntegration` will
76
+ # by default create a Sentry event from error logs made in step 1 if we do not prevent it from doing so.
77
+ ignore_logger("litestar")
78
+
79
+
80
+ class SentryLitestarASGIMiddleware(SentryAsgiMiddleware):
81
+ def __init__(self, app, span_origin=LitestarIntegration.origin):
82
+ # type: (ASGIApp, str) -> None
83
+
84
+ super().__init__(
85
+ app=app,
86
+ unsafe_context_data=False,
87
+ transaction_style="endpoint",
88
+ mechanism_type="asgi",
89
+ span_origin=span_origin,
90
+ asgi_version=3,
91
+ )
92
+
93
+ def _capture_request_exception(self, exc):
94
+ # type: (Exception) -> None
95
+ """Avoid catching exceptions from request handlers.
96
+
97
+ Those exceptions are already handled in Litestar.after_exception handler.
98
+ We still catch exceptions from application lifespan handlers.
99
+ """
100
+ pass
101
+
102
+
103
+ def patch_app_init():
104
+ # type: () -> None
105
+ """
106
+ Replaces the Litestar class's `__init__` function in order to inject `after_exception` handlers and set the
107
+ `SentryLitestarASGIMiddleware` as the outmost middleware in the stack.
108
+ See:
109
+ - https://docs.litestar.dev/2/usage/applications.html#after-exception
110
+ - https://docs.litestar.dev/2/usage/middleware/using-middleware.html
111
+ """
112
+ old__init__ = Litestar.__init__
113
+
114
+ @ensure_integration_enabled(LitestarIntegration, old__init__)
115
+ def injection_wrapper(self, *args, **kwargs):
116
+ # type: (Litestar, *Any, **Any) -> None
117
+ kwargs["after_exception"] = [
118
+ exception_handler,
119
+ *(kwargs.get("after_exception") or []),
120
+ ]
121
+
122
+ middleware = kwargs.get("middleware") or []
123
+ kwargs["middleware"] = [SentryLitestarASGIMiddleware, *middleware]
124
+ old__init__(self, *args, **kwargs)
125
+
126
+ Litestar.__init__ = injection_wrapper
127
+
128
+
129
+ def patch_middlewares():
130
+ # type: () -> None
131
+ old_resolve_middleware_stack = BaseRouteHandler.resolve_middleware
132
+
133
+ @ensure_integration_enabled(LitestarIntegration, old_resolve_middleware_stack)
134
+ def resolve_middleware_wrapper(self):
135
+ # type: (BaseRouteHandler) -> list[Middleware]
136
+ return [
137
+ enable_span_for_middleware(middleware)
138
+ for middleware in old_resolve_middleware_stack(self)
139
+ ]
140
+
141
+ BaseRouteHandler.resolve_middleware = resolve_middleware_wrapper
142
+
143
+
144
+ def enable_span_for_middleware(middleware):
145
+ # type: (Middleware) -> Middleware
146
+ if (
147
+ not hasattr(middleware, "__call__") # noqa: B004
148
+ or middleware is SentryLitestarASGIMiddleware
149
+ ):
150
+ return middleware
151
+
152
+ if isinstance(middleware, DefineMiddleware):
153
+ old_call = middleware.middleware.__call__ # type: ASGIApp
154
+ else:
155
+ old_call = middleware.__call__
156
+
157
+ async def _create_span_call(self, scope, receive, send):
158
+ # type: (MiddlewareProtocol, LitestarScope, Receive, Send) -> None
159
+ if sentry_sdk.get_client().get_integration(LitestarIntegration) is None:
160
+ return await old_call(self, scope, receive, send)
161
+
162
+ middleware_name = self.__class__.__name__
163
+ with sentry_sdk.start_span(
164
+ op=OP.MIDDLEWARE_LITESTAR,
165
+ name=middleware_name,
166
+ origin=LitestarIntegration.origin,
167
+ ) as middleware_span:
168
+ middleware_span.set_tag("litestar.middleware_name", middleware_name)
169
+
170
+ # Creating spans for the "receive" callback
171
+ async def _sentry_receive(*args, **kwargs):
172
+ # type: (*Any, **Any) -> Union[HTTPReceiveMessage, WebSocketReceiveMessage]
173
+ if sentry_sdk.get_client().get_integration(LitestarIntegration) is None:
174
+ return await receive(*args, **kwargs)
175
+ with sentry_sdk.start_span(
176
+ op=OP.MIDDLEWARE_LITESTAR_RECEIVE,
177
+ name=getattr(receive, "__qualname__", str(receive)),
178
+ origin=LitestarIntegration.origin,
179
+ ) as span:
180
+ span.set_tag("litestar.middleware_name", middleware_name)
181
+ return await receive(*args, **kwargs)
182
+
183
+ receive_name = getattr(receive, "__name__", str(receive))
184
+ receive_patched = receive_name == "_sentry_receive"
185
+ new_receive = _sentry_receive if not receive_patched else receive
186
+
187
+ # Creating spans for the "send" callback
188
+ async def _sentry_send(message):
189
+ # type: (Message) -> None
190
+ if sentry_sdk.get_client().get_integration(LitestarIntegration) is None:
191
+ return await send(message)
192
+ with sentry_sdk.start_span(
193
+ op=OP.MIDDLEWARE_LITESTAR_SEND,
194
+ name=getattr(send, "__qualname__", str(send)),
195
+ origin=LitestarIntegration.origin,
196
+ ) as span:
197
+ span.set_tag("litestar.middleware_name", middleware_name)
198
+ return await send(message)
199
+
200
+ send_name = getattr(send, "__name__", str(send))
201
+ send_patched = send_name == "_sentry_send"
202
+ new_send = _sentry_send if not send_patched else send
203
+
204
+ return await old_call(self, scope, new_receive, new_send)
205
+
206
+ not_yet_patched = old_call.__name__ not in ["_create_span_call"]
207
+
208
+ if not_yet_patched:
209
+ if isinstance(middleware, DefineMiddleware):
210
+ middleware.middleware.__call__ = _create_span_call
211
+ else:
212
+ middleware.__call__ = _create_span_call
213
+
214
+ return middleware
215
+
216
+
217
+ def patch_http_route_handle():
218
+ # type: () -> None
219
+ old_handle = HTTPRoute.handle
220
+
221
+ async def handle_wrapper(self, scope, receive, send):
222
+ # type: (HTTPRoute, HTTPScope, Receive, Send) -> None
223
+ if sentry_sdk.get_client().get_integration(LitestarIntegration) is None:
224
+ return await old_handle(self, scope, receive, send)
225
+
226
+ sentry_scope = sentry_sdk.get_isolation_scope()
227
+ request = scope["app"].request_class(scope=scope, receive=receive, send=send) # type: Request[Any, Any]
228
+ extracted_request_data = ConnectionDataExtractor(
229
+ parse_body=True, parse_query=True
230
+ )(request)
231
+ body = extracted_request_data.pop("body")
232
+
233
+ request_data = await body
234
+
235
+ def event_processor(event, _):
236
+ # type: (Event, Hint) -> Event
237
+ route_handler = scope.get("route_handler")
238
+
239
+ request_info = event.get("request", {})
240
+ request_info["content_length"] = len(scope.get("_body", b""))
241
+ if should_send_default_pii():
242
+ request_info["cookies"] = extracted_request_data["cookies"]
243
+ if request_data is not None:
244
+ request_info["data"] = request_data
245
+
246
+ func = None
247
+ if route_handler.name is not None:
248
+ tx_name = route_handler.name
249
+ # Accounts for use of type `Ref` in earlier versions of litestar without the need to reference it as a type
250
+ elif hasattr(route_handler.fn, "value"):
251
+ func = route_handler.fn.value
252
+ else:
253
+ func = route_handler.fn
254
+ if func is not None:
255
+ tx_name = transaction_from_function(func)
256
+
257
+ tx_info = {"source": SOURCE_FOR_STYLE["endpoint"]}
258
+
259
+ if not tx_name:
260
+ tx_name = _DEFAULT_TRANSACTION_NAME
261
+ tx_info = {"source": TransactionSource.ROUTE}
262
+
263
+ event.update(
264
+ {
265
+ "request": deepcopy(request_info),
266
+ "transaction": tx_name,
267
+ "transaction_info": tx_info,
268
+ }
269
+ )
270
+ return event
271
+
272
+ sentry_scope._name = LitestarIntegration.identifier
273
+ sentry_scope.add_event_processor(event_processor)
274
+
275
+ return await old_handle(self, scope, receive, send)
276
+
277
+ HTTPRoute.handle = handle_wrapper
278
+
279
+
280
+ def retrieve_user_from_scope(scope):
281
+ # type: (LitestarScope) -> Optional[dict[str, Any]]
282
+ scope_user = scope.get("user")
283
+ if isinstance(scope_user, dict):
284
+ return scope_user
285
+ if hasattr(scope_user, "asdict"): # dataclasses
286
+ return scope_user.asdict()
287
+
288
+ return None
289
+
290
+
291
+ @ensure_integration_enabled(LitestarIntegration)
292
+ def exception_handler(exc, scope):
293
+ # type: (Exception, LitestarScope) -> None
294
+ user_info = None # type: Optional[dict[str, Any]]
295
+ if should_send_default_pii():
296
+ user_info = retrieve_user_from_scope(scope)
297
+ if user_info and isinstance(user_info, dict):
298
+ sentry_scope = sentry_sdk.get_isolation_scope()
299
+ sentry_scope.set_user(user_info)
300
+
301
+ if isinstance(exc, HTTPException):
302
+ integration = sentry_sdk.get_client().get_integration(LitestarIntegration)
303
+ if (
304
+ integration is not None
305
+ and exc.status_code not in integration.failed_request_status_codes
306
+ ):
307
+ return
308
+
309
+ event, hint = event_from_exception(
310
+ exc,
311
+ client_options=sentry_sdk.get_client().options,
312
+ mechanism={"type": LitestarIntegration.identifier, "handled": False},
313
+ )
314
+
315
+ sentry_sdk.capture_event(event, hint=hint)