diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 02939e3112..12e01ec6bf 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -62,6 +62,7 @@ Looking to upgrade from Sentry SDK 1.x to 2.x? Here's a comprehensive list of wh - Removed support for Django 1.8, 1.9, 1.10. - Removed support for Flask 0.\*. - Removed support for gRPC < 1.39. +- Removed support for Tornado < 6. - Removed `last_event_id()` top level API. The last event ID is still returned by `capture_event()`, `capture_exception()` and `capture_message()` but the top level API `sentry_sdk.last_event_id()` has been removed. - Removed support for sending events to the `/store` endpoint. Everything is now sent to the `/envelope` endpoint. If you're on SaaS you don't have to worry about this, but if you're running Sentry yourself you'll need version `20.6.0` or higher of self-hosted Sentry. - The deprecated `with_locals` configuration option was removed. Use `include_local_variables` instead. See https://docs.sentry.io/platforms/python/configuration/options/#include-local-variables. diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index 4bb03249d2..6681037000 100644 --- a/sentry_sdk/integrations/tornado.py +++ b/sentry_sdk/integrations/tornado.py @@ -2,9 +2,10 @@ import contextlib from inspect import iscoroutinefunction +import sentry_sdk from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP -from sentry_sdk.hub import Hub, _should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import ( TRANSACTION_SOURCE_COMPONENT, TRANSACTION_SOURCE_ROUTE, @@ -12,6 +13,7 @@ from sentry_sdk.utils import ( HAS_REAL_CONTEXTVARS, CONTEXTVARS_ERROR_MESSAGE, + ensure_integration_enabled, event_from_exception, capture_internal_exceptions, transaction_from_function, @@ -49,8 +51,8 @@ class TornadoIntegration(Integration): @staticmethod def setup_once(): # type: () -> None - if TORNADO_VERSION < (5, 0): - raise DidNotEnable("Tornado 5+ required") + if TORNADO_VERSION < (6, 0): + raise DidNotEnable("Tornado 6.0+ required") if not HAS_REAL_CONTEXTVARS: # Tornado is async. We better have contextvars or we're going to leak @@ -98,21 +100,19 @@ def sentry_log_exception(self, ty, value, tb, *args, **kwargs): @contextlib.contextmanager def _handle_request_impl(self): # type: (RequestHandler) -> Generator[None, None, None] - hub = Hub.current - integration = hub.get_integration(TornadoIntegration) + integration = sentry_sdk.get_client().get_integration(TornadoIntegration) if integration is None: yield weak_handler = weakref.ref(self) - with Hub(hub) as hub: + with sentry_sdk.isolation_scope() as scope: headers = self.request.headers - with hub.configure_scope() as scope: - scope.clear_breadcrumbs() - processor = _make_event_processor(weak_handler) - scope.add_event_processor(processor) + scope.clear_breadcrumbs() + processor = _make_event_processor(weak_handler) + scope.add_event_processor(processor) transaction = continue_trace( headers, @@ -125,30 +125,25 @@ def _handle_request_impl(self): source=TRANSACTION_SOURCE_ROUTE, ) - with hub.start_transaction( + with sentry_sdk.start_transaction( transaction, custom_sampling_context={"tornado_request": self.request} ): yield +@ensure_integration_enabled(TornadoIntegration) def _capture_exception(ty, value, tb): # type: (type, BaseException, Any) -> None - hub = Hub.current - if hub.get_integration(TornadoIntegration) is None: - return if isinstance(value, HTTPError): return - # If an integration is there, a client has to be there. - client = hub.client # type: Any - event, hint = event_from_exception( (ty, value, tb), - client_options=client.options, + client_options=sentry_sdk.get_client().options, mechanism={"type": "tornado", "handled": False}, ) - hub.capture_event(event, hint=hint) + sentry_sdk.capture_event(event, hint=hint) def _make_event_processor(weak_handler): @@ -184,7 +179,7 @@ def tornado_processor(event, hint): request_info["headers"] = _filter_headers(dict(request.headers)) with capture_internal_exceptions(): - if handler.current_user and _should_send_default_pii(): + if handler.current_user and should_send_default_pii(): event.setdefault("user", {}).setdefault("is_authenticated", True) return event diff --git a/tests/integrations/tornado/test_tornado.py b/tests/integrations/tornado/test_tornado.py index 49fb36d561..181c17cd49 100644 --- a/tests/integrations/tornado/test_tornado.py +++ b/tests/integrations/tornado/test_tornado.py @@ -112,7 +112,7 @@ def test_basic(tornado_testcase, sentry_init, capture_events): ], ) def test_transactions(tornado_testcase, sentry_init, capture_events, handler, code): - sentry_init(integrations=[TornadoIntegration()], traces_sample_rate=1.0, debug=True) + sentry_init(integrations=[TornadoIntegration()], traces_sample_rate=1.0) events = capture_events() client = tornado_testcase(Application([(r"/hi", handler)])) diff --git a/tox.ini b/tox.ini index 11d9acfaec..8313d7df11 100644 --- a/tox.ini +++ b/tox.ini @@ -225,7 +225,7 @@ envlist = {py3.8,py3.11,py3.12}-strawberry-latest # Tornado - {py3.7,py3.9}-tornado-v{5} + {py3.8,py3.11,py3.12}-tornado-v{6.0} {py3.8,py3.11,py3.12}-tornado-v{6} {py3.8,py3.11,py3.12}-tornado-latest @@ -562,7 +562,7 @@ deps = strawberry-latest: strawberry-graphql[fastapi,flask] # Tornado - tornado-v5: tornado~=5.0 + tornado-v6.0: tornado~=6.0.0 tornado-v6: tornado~=6.0 tornado-latest: tornado