diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index bfdd4e5472..91d812369c 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -190,12 +190,9 @@ def init(*args, **kwargs): def create_trace_config(): # type: () -> TraceConfig + @ensure_integration_enabled_async(AioHttpIntegration) async def on_request_start(session, trace_config_ctx, params): # type: (ClientSession, SimpleNamespace, TraceRequestStartParams) -> None - client = sentry_sdk.get_client() - if client.get_integration(AioHttpIntegration) is None: - return - method = params.method.upper() parsed_url = None @@ -213,6 +210,8 @@ async def on_request_start(session, trace_config_ctx, params): span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query) span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment) + client = sentry_sdk.get_client() + if should_propagate_trace(client, str(params.url)): for key, value in Scope.get_current_scope().iter_trace_propagation_headers( span=span diff --git a/sentry_sdk/integrations/asyncpg.py b/sentry_sdk/integrations/asyncpg.py index 994ae4c348..f538934bc2 100644 --- a/sentry_sdk/integrations/asyncpg.py +++ b/sentry_sdk/integrations/asyncpg.py @@ -58,14 +58,13 @@ def setup_once() -> None: def _wrap_execute(f: Callable[..., Awaitable[T]]) -> Callable[..., Awaitable[T]]: + @ensure_integration_enabled_async(AsyncPGIntegration, f) async def _inner(*args: Any, **kwargs: Any) -> T: - integration = sentry_sdk.get_client().get_integration(AsyncPGIntegration) - # Avoid recording calls to _execute twice. # Calls to Connection.execute with args also call # Connection._execute, which is recorded separately # args[0] = the connection object, args[1] is the query - if integration is None or len(args) > 2: + if len(args) > 2: return await f(*args, **kwargs) query = args[1] diff --git a/sentry_sdk/integrations/atexit.py b/sentry_sdk/integrations/atexit.py index c3139e3b28..d11e35fafa 100644 --- a/sentry_sdk/integrations/atexit.py +++ b/sentry_sdk/integrations/atexit.py @@ -6,7 +6,7 @@ from sentry_sdk import Scope from sentry_sdk.utils import logger from sentry_sdk.integrations import Integration - +from sentry_sdk.utils import ensure_integration_enabled from sentry_sdk._types import TYPE_CHECKING if TYPE_CHECKING: @@ -44,13 +44,13 @@ def __init__(self, callback=None): def setup_once(): # type: () -> None @atexit.register + @ensure_integration_enabled(AtexitIntegration) def _shutdown(): # type: () -> None logger.debug("atexit: got shutdown signal") client = sentry_sdk.get_client() integration = client.get_integration(AtexitIntegration) - if integration is not None: - logger.debug("atexit: shutting down client") - Scope.get_isolation_scope().end_session() - client.close(callback=integration.callback) + logger.debug("atexit: shutting down client") + Scope.get_isolation_scope().end_session() + client.close(callback=integration.callback) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 16247884d1..bd1e3619de 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -11,6 +11,7 @@ from sentry_sdk.utils import ( AnnotatedValue, capture_internal_exceptions, + ensure_integration_enabled, event_from_exception, logger, TimeoutThread, @@ -37,12 +38,10 @@ def _wrap_init_error(init_error): # type: (F) -> F + @ensure_integration_enabled(AwsLambdaIntegration, init_error) def sentry_init_error(*args, **kwargs): # type: (*Any, **Any) -> Any client = sentry_sdk.get_client() - integration = client.get_integration(AwsLambdaIntegration) - if integration is None: - return init_error(*args, **kwargs) with capture_internal_exceptions(): Scope.get_isolation_scope().clear_breadcrumbs() @@ -63,6 +62,7 @@ def sentry_init_error(*args, **kwargs): def _wrap_handler(handler): # type: (F) -> F + @ensure_integration_enabled(AwsLambdaIntegration, handler) def sentry_handler(aws_event, aws_context, *args, **kwargs): # type: (Any, Any, *Any, **Any) -> Any @@ -91,8 +91,6 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): client = sentry_sdk.get_client() integration = client.get_integration(AwsLambdaIntegration) - if integration is None: - return handler(aws_event, aws_context, *args, **kwargs) configured_time = aws_context.get_remaining_time_in_millis() diff --git a/sentry_sdk/integrations/boto3.py b/sentry_sdk/integrations/boto3.py index 3de4a67d3b..e1c9ae698f 100644 --- a/sentry_sdk/integrations/boto3.py +++ b/sentry_sdk/integrations/boto3.py @@ -6,7 +6,12 @@ from sentry_sdk.tracing import Span from sentry_sdk._types import TYPE_CHECKING -from sentry_sdk.utils import capture_internal_exceptions, parse_url, parse_version +from sentry_sdk.utils import ( + capture_internal_exceptions, + ensure_integration_enabled, + parse_url, + parse_version, +) if TYPE_CHECKING: from typing import Any @@ -57,11 +62,9 @@ def sentry_patched_init(self, *args, **kwargs): BaseClient.__init__ = sentry_patched_init +@ensure_integration_enabled(Boto3Integration) def _sentry_request_created(service_id, request, operation_name, **kwargs): # type: (str, AWSRequest, str, **Any) -> None - if sentry_sdk.get_client().get_integration(Boto3Integration) is None: - return - description = "aws.%s.%s" % (service_id, operation_name) span = sentry_sdk.start_span( op=OP.HTTP_CLIENT, diff --git a/sentry_sdk/integrations/bottle.py b/sentry_sdk/integrations/bottle.py index 7acfa9a8dd..472f0a352b 100644 --- a/sentry_sdk/integrations/bottle.py +++ b/sentry_sdk/integrations/bottle.py @@ -77,11 +77,10 @@ def sentry_patched_wsgi_app(self, environ, start_response): old_handle = Bottle._handle + @ensure_integration_enabled(BottleIntegration, old_handle) def _patched_handle(self, environ): # type: (Bottle, Dict[str, Any]) -> Any integration = sentry_sdk.get_client().get_integration(BottleIntegration) - if integration is None: - return old_handle(self, environ) scope = Scope.get_isolation_scope() scope._name = "bottle" @@ -96,13 +95,11 @@ def _patched_handle(self, environ): old_make_callback = Route._make_callback + @ensure_integration_enabled(BottleIntegration, old_make_callback) def patched_make_callback(self, *args, **kwargs): # type: (Route, *object, **object) -> Any client = sentry_sdk.get_client() - integration = client.get_integration(BottleIntegration) prepared_callback = old_make_callback(self, *args, **kwargs) - if integration is None: - return prepared_callback def wrapped_callback(*args, **kwargs): # type: (*object, **object) -> Any diff --git a/sentry_sdk/integrations/clickhouse_driver.py b/sentry_sdk/integrations/clickhouse_driver.py index 9c0a974349..31eb971e33 100644 --- a/sentry_sdk/integrations/clickhouse_driver.py +++ b/sentry_sdk/integrations/clickhouse_driver.py @@ -4,7 +4,7 @@ from sentry_sdk.tracing import Span from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.scope import should_send_default_pii -from sentry_sdk.utils import capture_internal_exceptions +from sentry_sdk.utils import capture_internal_exceptions, ensure_integration_enabled from typing import TypeVar @@ -74,9 +74,8 @@ def setup_once() -> None: def _wrap_start(f: Callable[P, T]) -> Callable[P, T]: + @ensure_integration_enabled(ClickhouseDriverIntegration, f) def _inner(*args: P.args, **kwargs: P.kwargs) -> T: - if sentry_sdk.get_client().get_integration(ClickhouseDriverIntegration) is None: - return f(*args, **kwargs) connection = args[0] query = args[1] query_id = args[2] if len(args) > 2 else kwargs.get("query_id") diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 1683804e48..4e7bc00a0f 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -392,13 +392,11 @@ def _set_transaction_name_and_source(scope, transaction_style, request): pass +@ensure_integration_enabled(DjangoIntegration) def _before_get_response(request): # type: (WSGIRequest) -> None integration = sentry_sdk.get_client().get_integration(DjangoIntegration) - if integration is None: - return - _patch_drf() scope = Scope.get_current_scope() @@ -423,10 +421,11 @@ def _attempt_resolve_again(request, scope, transaction_style): _set_transaction_name_and_source(scope, transaction_style, request) +@ensure_integration_enabled(DjangoIntegration) def _after_get_response(request): # type: (WSGIRequest) -> None integration = sentry_sdk.get_client().get_integration(DjangoIntegration) - if integration is None or integration.transaction_style != "url": + if integration.transaction_style != "url": return scope = Scope.get_current_scope() @@ -492,21 +491,22 @@ def wsgi_request_event_processor(event, hint): return wsgi_request_event_processor +@ensure_integration_enabled(DjangoIntegration) def _got_request_exception(request=None, **kwargs): # type: (WSGIRequest, **Any) -> None client = sentry_sdk.get_client() integration = client.get_integration(DjangoIntegration) - if integration is not None: - if request is not None and integration.transaction_style == "url": - scope = Scope.get_current_scope() - _attempt_resolve_again(request, scope, integration.transaction_style) - - event, hint = event_from_exception( - sys.exc_info(), - client_options=client.options, - mechanism={"type": "django", "handled": False}, - ) - sentry_sdk.capture_event(event, hint=hint) + + if request is not None and integration.transaction_style == "url": + scope = Scope.get_current_scope() + _attempt_resolve_again(request, scope, integration.transaction_style) + + event, hint = event_from_exception( + sys.exc_info(), + client_options=client.options, + mechanism={"type": "django", "handled": False}, + ) + sentry_sdk.capture_event(event, hint=hint) class DjangoRequestExtractor(RequestExtractor): diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index 15ea0e1b99..0c75ad7955 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -65,11 +65,9 @@ def patch_templates(): real_rendered_content = SimpleTemplateResponse.rendered_content @property # type: ignore + @ensure_integration_enabled(DjangoIntegration, real_rendered_content.fget) def rendered_content(self): # type: (SimpleTemplateResponse) -> str - if sentry_sdk.get_client().get_integration(DjangoIntegration) is None: - return real_rendered_content.fget(self) - with sentry_sdk.start_span( op=OP.TEMPLATE_RENDER, description=_get_template_name_description(self.template_name), diff --git a/sentry_sdk/integrations/excepthook.py b/sentry_sdk/integrations/excepthook.py index a2146bee9e..d638ef2f9f 100644 --- a/sentry_sdk/integrations/excepthook.py +++ b/sentry_sdk/integrations/excepthook.py @@ -1,7 +1,11 @@ import sys import sentry_sdk -from sentry_sdk.utils import capture_internal_exceptions, event_from_exception +from sentry_sdk.utils import ( + capture_internal_exceptions, + ensure_integration_enabled, + event_from_exception, +) from sentry_sdk.integrations import Integration from sentry_sdk._types import TYPE_CHECKING @@ -43,11 +47,12 @@ def setup_once(): def _make_excepthook(old_excepthook): # type: (Excepthook) -> Excepthook + @ensure_integration_enabled(ExcepthookIntegration, old_excepthook) def sentry_sdk_excepthook(type_, value, traceback): # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration) - if integration is not None and _should_send(integration.always_run): + if _should_send(integration.always_run): with capture_internal_exceptions(): event, hint = event_from_exception( (type_, value, traceback), diff --git a/sentry_sdk/integrations/falcon.py b/sentry_sdk/integrations/falcon.py index 7fe8c9e62f..61c11e11d5 100644 --- a/sentry_sdk/integrations/falcon.py +++ b/sentry_sdk/integrations/falcon.py @@ -6,6 +6,7 @@ from sentry_sdk.tracing import SOURCE_FOR_STYLE from sentry_sdk.utils import ( capture_internal_exceptions, + ensure_integration_enabled, event_from_exception, parse_version, ) @@ -167,6 +168,7 @@ def _patch_handle_exception(): # type: () -> None original_handle_exception = falcon_app_class._handle_exception + @ensure_integration_enabled(FalconIntegration, original_handle_exception) def sentry_patched_handle_exception(self, *args): # type: (falcon.API, *Any) -> Any # NOTE(jmagnusson): falcon 2.0 changed falcon.API._handle_exception @@ -187,14 +189,10 @@ def sentry_patched_handle_exception(self, *args): # capture_internal_exceptions block above. return was_handled - client = sentry_sdk.get_client() - integration = client.get_integration(FalconIntegration) - - if integration is not None and _exception_leads_to_http_5xx(ex, response): - # If an integration is there, a client has to be there. + if _exception_leads_to_http_5xx(ex, response): event, hint = event_from_exception( ex, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "falcon", "handled": False}, ) sentry_sdk.capture_event(event, hint=hint) diff --git a/sentry_sdk/integrations/flask.py b/sentry_sdk/integrations/flask.py index d511ba7617..52b843c911 100644 --- a/sentry_sdk/integrations/flask.py +++ b/sentry_sdk/integrations/flask.py @@ -76,9 +76,11 @@ def setup_once(): old_app = Flask.__call__ - @ensure_integration_enabled(FlaskIntegration, old_app) def sentry_patched_wsgi_app(self, environ, start_response): # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse + if sentry_sdk.get_client().get_integration(FlaskIntegration) is None: + return old_app(self, environ, start_response) + return SentryWsgiMiddleware(lambda *a, **kw: old_app(self, *a, **kw))( environ, start_response ) @@ -112,12 +114,10 @@ def _set_transaction_name_and_source(scope, transaction_style, request): pass +@ensure_integration_enabled(FlaskIntegration) def _request_started(app, **kwargs): # type: (Flask, **Any) -> None integration = sentry_sdk.get_client().get_integration(FlaskIntegration) - if integration is None: - return - request = flask_request._get_current_object() # Set the transaction name and source here, @@ -192,15 +192,12 @@ def inner(event, hint): return inner +@ensure_integration_enabled(FlaskIntegration) def _capture_exception(sender, exception, **kwargs): # type: (Flask, Union[ValueError, BaseException], **Any) -> None - client = sentry_sdk.get_client() - if client.get_integration(FlaskIntegration) is None: - return - event, hint = event_from_exception( exception, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "flask", "handled": False}, ) diff --git a/sentry_sdk/integrations/gcp.py b/sentry_sdk/integrations/gcp.py index f70deb55e4..0cab8f9b26 100644 --- a/sentry_sdk/integrations/gcp.py +++ b/sentry_sdk/integrations/gcp.py @@ -13,6 +13,7 @@ from sentry_sdk.utils import ( AnnotatedValue, capture_internal_exceptions, + ensure_integration_enabled, event_from_exception, logger, TimeoutThread, @@ -38,13 +39,12 @@ def _wrap_func(func): # type: (F) -> F + @ensure_integration_enabled(GcpIntegration, func) def sentry_func(functionhandler, gcp_event, *args, **kwargs): # type: (Any, Any, *Any, **Any) -> Any client = sentry_sdk.get_client() integration = client.get_integration(GcpIntegration) - if integration is None: - return func(functionhandler, gcp_event, *args, **kwargs) configured_time = environ.get("FUNCTION_TIMEOUT_SEC") if not configured_time: diff --git a/sentry_sdk/integrations/graphene.py b/sentry_sdk/integrations/graphene.py index 7ae519c426..1931b12a71 100644 --- a/sentry_sdk/integrations/graphene.py +++ b/sentry_sdk/integrations/graphene.py @@ -3,6 +3,8 @@ from sentry_sdk.scope import Scope, should_send_default_pii from sentry_sdk.utils import ( capture_internal_exceptions, + ensure_integration_enabled, + ensure_integration_enabled_async, event_from_exception, package_version, ) @@ -45,13 +47,9 @@ def _patch_graphql(): old_graphql_sync = graphene_schema.graphql_sync old_graphql_async = graphene_schema.graphql + @ensure_integration_enabled(GrapheneIntegration, old_graphql_sync) def _sentry_patched_graphql_sync(schema, source, *args, **kwargs): # type: (GraphQLSchema, Union[str, Source], Any, Any) -> ExecutionResult - client = sentry_sdk.get_client() - integration = client.get_integration(GrapheneIntegration) - if integration is None: - return old_graphql_sync(schema, source, *args, **kwargs) - scope = Scope.get_isolation_scope() scope.add_event_processor(_event_processor) @@ -61,9 +59,9 @@ def _sentry_patched_graphql_sync(schema, source, *args, **kwargs): for error in result.errors or []: event, hint = event_from_exception( error, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={ - "type": integration.identifier, + "type": GrapheneIntegration.identifier, "handled": False, }, ) @@ -71,13 +69,9 @@ def _sentry_patched_graphql_sync(schema, source, *args, **kwargs): return result + @ensure_integration_enabled_async(GrapheneIntegration, old_graphql_async) async def _sentry_patched_graphql_async(schema, source, *args, **kwargs): # type: (GraphQLSchema, Union[str, Source], Any, Any) -> ExecutionResult - client = sentry_sdk.get_client() - integration = client.get_integration(GrapheneIntegration) - if integration is None: - return await old_graphql_async(schema, source, *args, **kwargs) - scope = Scope.get_isolation_scope() scope.add_event_processor(_event_processor) @@ -87,9 +81,9 @@ async def _sentry_patched_graphql_async(schema, source, *args, **kwargs): for error in result.errors or []: event, hint = event_from_exception( error, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={ - "type": integration.identifier, + "type": GrapheneIntegration.identifier, "handled": False, }, ) diff --git a/sentry_sdk/integrations/pyramid.py b/sentry_sdk/integrations/pyramid.py index b1638034a3..523ee4b5ec 100644 --- a/sentry_sdk/integrations/pyramid.py +++ b/sentry_sdk/integrations/pyramid.py @@ -72,18 +72,18 @@ def setup_once(): old_call_view = router._call_view + @ensure_integration_enabled(PyramidIntegration, old_call_view) def sentry_patched_call_view(registry, request, *args, **kwargs): # type: (Any, Request, *Any, **Any) -> Response integration = sentry_sdk.get_client().get_integration(PyramidIntegration) - if integration is not None: - _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request - ) - scope = Scope.get_isolation_scope() - scope.add_event_processor( - _make_event_processor(weakref.ref(request), integration) - ) + _set_transaction_name_and_source( + Scope.get_current_scope(), integration.transaction_style, request + ) + scope = Scope.get_isolation_scope() + scope.add_event_processor( + _make_event_processor(weakref.ref(request), integration) + ) return old_call_view(registry, request, *args, **kwargs) @@ -130,18 +130,15 @@ def sentry_patched_inner_wsgi_call(environ, start_response): router.Router.__call__ = sentry_patched_wsgi_call +@ensure_integration_enabled(PyramidIntegration) def _capture_exception(exc_info): # type: (ExcInfo) -> None if exc_info[0] is None or issubclass(exc_info[0], HTTPException): return - client = sentry_sdk.get_client() - if client.get_integration(PyramidIntegration) is None: - return - event, hint = event_from_exception( exc_info, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "pyramid", "handled": False}, ) diff --git a/sentry_sdk/integrations/quart.py b/sentry_sdk/integrations/quart.py index baa975f12e..21a0fc3fd9 100644 --- a/sentry_sdk/integrations/quart.py +++ b/sentry_sdk/integrations/quart.py @@ -12,6 +12,7 @@ from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, + ensure_integration_enabled_async, event_from_exception, ) from sentry_sdk._types import TYPE_CHECKING @@ -113,14 +114,9 @@ def decorator(old_func): ): @wraps(old_func) + @ensure_integration_enabled(QuartIntegration, old_func) def _sentry_func(*args, **kwargs): # type: (*Any, **Any) -> Any - integration = sentry_sdk.get_client().get_integration( - QuartIntegration - ) - if integration is None: - return old_func(*args, **kwargs) - scope = Scope.get_isolation_scope() if scope.profile is not None: scope.profile.active_thread_id = ( @@ -154,11 +150,10 @@ def _set_transaction_name_and_source(scope, transaction_style, request): pass +@ensure_integration_enabled_async(QuartIntegration) async def _request_websocket_started(app, **kwargs): # type: (Quart, **Any) -> None integration = sentry_sdk.get_client().get_integration(QuartIntegration) - if integration is None: - return if has_request_context(): request_websocket = request._get_current_object() @@ -205,15 +200,12 @@ def inner(event, hint): return inner +@ensure_integration_enabled_async(QuartIntegration) async def _capture_exception(sender, exception, **kwargs): # type: (Quart, Union[ValueError, BaseException], **Any) -> None - client = sentry_sdk.get_client() - if client.get_integration(QuartIntegration) is None: - return - event, hint = event_from_exception( exception, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "quart", "handled": False}, ) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index e6c2f5e5ea..578aa04598 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -13,6 +13,8 @@ from sentry_sdk.scope import Scope from sentry_sdk.utils import ( capture_internal_exceptions, + ensure_integration_enabled, + ensure_integration_enabled_async, event_from_exception, HAS_REAL_CONTEXTVARS, CONTEXTVARS_ERROR_MESSAGE, @@ -272,11 +274,9 @@ async def sentry_wrapped_error_handler(request, exception): return sentry_wrapped_error_handler +@ensure_integration_enabled_async(SanicIntegration, old_handle_request) async def _legacy_handle_request(self, request, *args, **kwargs): # type: (Any, Request, *Any, **Any) -> Any - if sentry_sdk.get_client().get_integration(SanicIntegration) is None: - return old_handle_request(self, request, *args, **kwargs) - weak_request = weakref.ref(request) with sentry_sdk.isolation_scope() as scope: @@ -320,17 +320,13 @@ def _legacy_router_get(self, *args): return rv +@ensure_integration_enabled(SanicIntegration) def _capture_exception(exception): # type: (Union[Tuple[Optional[type], Optional[BaseException], Any], BaseException]) -> None - client = sentry_sdk.get_client() - integration = client.get_integration(SanicIntegration) - if integration is None: - return - with capture_internal_exceptions(): event, hint = event_from_exception( exception, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "sanic", "handled": False}, ) sentry_sdk.capture_event(event, hint=hint) diff --git a/sentry_sdk/integrations/sqlalchemy.py b/sentry_sdk/integrations/sqlalchemy.py index c766019e68..9c438ca3df 100644 --- a/sentry_sdk/integrations/sqlalchemy.py +++ b/sentry_sdk/integrations/sqlalchemy.py @@ -4,7 +4,11 @@ from sentry_sdk.db.explain_plan.sqlalchemy import attach_explain_plan_to_span from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.tracing_utils import add_query_source, record_sql_queries -from sentry_sdk.utils import capture_internal_exceptions, parse_version +from sentry_sdk.utils import ( + capture_internal_exceptions, + ensure_integration_enabled, + parse_version, +) try: from sqlalchemy.engine import Engine # type: ignore @@ -43,13 +47,11 @@ def setup_once(): listen(Engine, "handle_error", _handle_error) +@ensure_integration_enabled(SqlalchemyIntegration) def _before_cursor_execute( conn, cursor, statement, parameters, context, executemany, *args ): # type: (Any, Any, Any, Any, Any, bool, *Any) -> None - if sentry_sdk.get_client().get_integration(SqlalchemyIntegration) is None: - return - ctx_mgr = record_sql_queries( cursor, statement, @@ -77,11 +79,9 @@ def _before_cursor_execute( context._sentry_sql_span = span +@ensure_integration_enabled(SqlalchemyIntegration) def _after_cursor_execute(conn, cursor, statement, parameters, context, *args): # type: (Any, Any, Any, Any, Any, *Any) -> None - if sentry_sdk.get_client().get_integration(SqlalchemyIntegration) is None: - return - ctx_mgr = getattr( context, "_sentry_sql_span_manager", None ) # type: Optional[ContextManager[Any]] diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index db48062cc0..eafc82f6ed 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -21,6 +21,7 @@ AnnotatedValue, capture_internal_exceptions, ensure_integration_enabled, + ensure_integration_enabled_async, event_from_exception, logger, parse_version, @@ -165,15 +166,12 @@ async def _sentry_send(*args, **kwargs): return middleware_class +@ensure_integration_enabled(StarletteIntegration) def _capture_exception(exception, handled=False): # type: (BaseException, **Any) -> None - client = sentry_sdk.get_client() - if client.get_integration(StarletteIntegration) is None: - return - event, hint = event_from_exception( exception, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": StarletteIntegration.identifier, "handled": handled}, ) @@ -252,6 +250,7 @@ async def _sentry_exceptionmiddleware_call(self, scope, receive, send): middleware_class.__call__ = _sentry_exceptionmiddleware_call +@ensure_integration_enabled(StarletteIntegration) def _add_user_to_sentry_scope(scope): # type: (Dict[str, Any]) -> None """ @@ -264,9 +263,6 @@ def _add_user_to_sentry_scope(scope): if not should_send_default_pii(): return - if sentry_sdk.get_client().get_integration(StarletteIntegration) is None: - return - user_info = {} # type: Dict[str, Any] starlette_user = scope["user"] @@ -341,11 +337,10 @@ def patch_asgi_app(): """ old_app = Starlette.__call__ + @ensure_integration_enabled_async(StarletteIntegration, old_app) async def _sentry_patched_asgi_app(self, scope, receive, send): # type: (Starlette, StarletteScope, Receive, Send) -> None integration = sentry_sdk.get_client().get_integration(StarletteIntegration) - if integration is None: - return await old_app(self, scope, receive, send) middleware = SentryAsgiMiddleware( lambda *a, **kw: old_app(self, *a, **kw), @@ -382,13 +377,12 @@ def _sentry_request_response(func): is_coroutine = _is_async_callable(old_func) if is_coroutine: + @ensure_integration_enabled_async(StarletteIntegration, old_func) async def _sentry_async_func(*args, **kwargs): # type: (*Any, **Any) -> Any integration = sentry_sdk.get_client().get_integration( StarletteIntegration ) - if integration is None: - return await old_func(*args, **kwargs) request = args[0] diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 1ee2e479ea..fdfe21d8ff 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -6,7 +6,12 @@ from sentry_sdk.integrations.asgi import SentryAsgiMiddleware from sentry_sdk.scope import Scope as SentryScope, should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE -from sentry_sdk.utils import event_from_exception, transaction_from_function +from sentry_sdk.utils import ( + ensure_integration_enabled, + ensure_integration_enabled_async, + event_from_exception, + transaction_from_function, +) try: from starlite import Request, Starlite, State # type: ignore @@ -174,14 +179,10 @@ async def _sentry_send(message: "Message") -> None: def patch_http_route_handle() -> None: old_handle = HTTPRoute.handle + @ensure_integration_enabled_async(StarliteIntegration, old_handle) async def handle_wrapper( self: "HTTPRoute", scope: "HTTPScope", receive: "Receive", send: "Send" ) -> None: - integration: StarliteIntegration = sentry_sdk.get_client().get_integration( - StarliteIntegration - ) - if integration is None: - return await old_handle(self, scope, receive, send) sentry_scope = SentryScope.get_isolation_scope() request: "Request[Any, Any]" = scope["app"].request_class( @@ -255,11 +256,8 @@ def retrieve_user_from_scope(scope: "StarliteScope") -> "Optional[Dict[str, Any] return None +@ensure_integration_enabled(StarliteIntegration) def exception_handler(exc: Exception, scope: "StarliteScope", _: "State") -> None: - client = sentry_sdk.get_client() - if client.get_integration(StarliteIntegration) is None: - return - user_info: "Optional[Dict[str, Any]]" = None if should_send_default_pii(): user_info = retrieve_user_from_scope(scope) @@ -269,7 +267,7 @@ def exception_handler(exc: Exception, scope: "StarliteScope", _: "State") -> Non event, hint = event_from_exception( exc, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": StarliteIntegration.identifier, "handled": False}, ) diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index 70be648ed5..10d21464d1 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -85,12 +85,10 @@ def _patch_schema_init(): # type: () -> None old_schema_init = Schema.__init__ + @ensure_integration_enabled(StrawberryIntegration, old_schema_init) def _sentry_patched_schema_init(self, *args, **kwargs): # type: (Schema, Any, Any) -> None integration = sentry_sdk.get_client().get_integration(StrawberryIntegration) - if integration is None: - return old_schema_init(self, *args, **kwargs) - extensions = kwargs.get("extensions") or [] if integration.async_execution is not None: @@ -308,13 +306,9 @@ def _sentry_patched_sync_view_handle_errors(self, errors, response_data): old_sync_view_handle_errors(self, errors, response_data) _sentry_patched_handle_errors(self, errors, response_data) + @ensure_integration_enabled(StrawberryIntegration) def _sentry_patched_handle_errors(self, errors, response_data): # type: (Any, List[GraphQLError], GraphQLHTTPResponse) -> None - client = sentry_sdk.get_client() - integration = client.get_integration(StrawberryIntegration) - if integration is None: - return - if not errors: return @@ -326,9 +320,9 @@ def _sentry_patched_handle_errors(self, errors, response_data): for error in errors: event, hint = event_from_exception( error, - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={ - "type": integration.identifier, + "type": StrawberryIntegration.identifier, "handled": False, }, ) diff --git a/sentry_sdk/integrations/threading.py b/sentry_sdk/integrations/threading.py index 0c7bff3cd9..63b6e13846 100644 --- a/sentry_sdk/integrations/threading.py +++ b/sentry_sdk/integrations/threading.py @@ -7,6 +7,7 @@ from sentry_sdk.integrations import Integration from sentry_sdk.scope import Scope, use_isolation_scope, use_scope from sentry_sdk.utils import ( + ensure_integration_enabled, event_from_exception, capture_internal_exceptions, logger, @@ -49,30 +50,30 @@ def setup_once(): old_start = Thread.start @wraps(old_start) + @ensure_integration_enabled(ThreadingIntegration, old_start) def sentry_start(self, *a, **kw): # type: (Thread, *Any, **Any) -> Any integration = sentry_sdk.get_client().get_integration(ThreadingIntegration) - if integration is not None: - if integration.propagate_scope: - isolation_scope = sentry_sdk.Scope.get_isolation_scope() - current_scope = sentry_sdk.Scope.get_current_scope() - else: - isolation_scope = None - current_scope = None - - # Patching instance methods in `start()` creates a reference cycle if - # done in a naive way. See - # https://github.com/getsentry/sentry-python/pull/434 - # - # In threading module, using current_thread API will access current thread instance - # without holding it to avoid a reference cycle in an easier way. - with capture_internal_exceptions(): - new_run = _wrap_run( - isolation_scope, - current_scope, - getattr(self.run, "__func__", self.run), - ) - self.run = new_run # type: ignore + if integration.propagate_scope: + isolation_scope = sentry_sdk.Scope.get_isolation_scope() + current_scope = sentry_sdk.Scope.get_current_scope() + else: + isolation_scope = None + current_scope = None + + # Patching instance methods in `start()` creates a reference cycle if + # done in a naive way. See + # https://github.com/getsentry/sentry-python/pull/434 + # + # In threading module, using current_thread API will access current thread instance + # without holding it to avoid a reference cycle in an easier way. + with capture_internal_exceptions(): + new_run = _wrap_run( + isolation_scope, + current_scope, + getattr(self.run, "__func__", self.run), + ) + self.run = new_run # type: ignore return old_start(self, *a, **kw) diff --git a/sentry_sdk/integrations/trytond.py b/sentry_sdk/integrations/trytond.py index f9e631455f..da8fc84df1 100644 --- a/sentry_sdk/integrations/trytond.py +++ b/sentry_sdk/integrations/trytond.py @@ -1,7 +1,7 @@ import sentry_sdk from sentry_sdk.integrations import Integration from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware -from sentry_sdk.utils import event_from_exception +from sentry_sdk.utils import ensure_integration_enabled, event_from_exception from trytond.exceptions import TrytonException # type: ignore from trytond.wsgi import app # type: ignore @@ -20,13 +20,12 @@ def __init__(self): # type: () -> None def setup_once(): # type: () -> None app.wsgi_app = SentryWsgiMiddleware(app.wsgi_app) + @ensure_integration_enabled(TrytondWSGIIntegration) def error_handler(e): # type: (Exception) -> None - client = sentry_sdk.get_client() - if client.get_integration(TrytondWSGIIntegration) is None: - return - elif isinstance(e, TrytonException): + if isinstance(e, TrytonException): return else: + client = sentry_sdk.get_client() event, hint = event_from_exception( e, client_options=client.options,