From c2af1b0ded09d8535ac660e3f21cf9d7f61122c3 Mon Sep 17 00:00:00 2001 From: Daniel Szoke <7881302+szokeasaurusrex@users.noreply.github.com> Date: Thu, 6 Jun 2024 10:24:11 -0400 Subject: [PATCH] feat(tracing): Warn if not-started transaction entered (#3003) Users who enter a transaction without calling `start_transaction` likely intended to start the transaction, since without a call to `start_transaction`, their transaction will not get sent to Sentry. This warning message clarifies this behavior, and could help avoid the confusion that led to issue #2990. Also, add tests to ensure the message is logged. --- sentry_sdk/tracing.py | 19 +++++++++++++++++++ tests/tracing/test_misc.py | 16 ++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index a6b1905a3c..de07969822 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -714,8 +714,27 @@ def __repr__(self): ) ) + def _possibly_started(self): + # type: () -> bool + """Returns whether the transaction might have been started. + + If this returns False, we know that the transaction was not started + with sentry_sdk.start_transaction, and therefore the transaction will + be discarded. + """ + + # We must explicitly check self.sampled is False since self.sampled can be None + return self._span_recorder is not None or self.sampled is False + def __enter__(self): # type: () -> Transaction + if not self._possibly_started(): + logger.warning( + "Transaction was entered without being started with sentry_sdk.start_transaction." + "The transaction will not be sent to Sentry. To fix, start the transaction by" + "passing it to sentry_sdk.start_transaction." + ) + super().__enter__() if self._profile is not None: diff --git a/tests/tracing/test_misc.py b/tests/tracing/test_misc.py index af1837f12c..e1006ef1bb 100644 --- a/tests/tracing/test_misc.py +++ b/tests/tracing/test_misc.py @@ -401,3 +401,19 @@ def test_transaction_dropeed_sampled_false(sentry_init): mock_logger.debug.assert_any_call( "Discarding transaction because it was not started with sentry_sdk.start_transaction" ) + + +def test_transaction_not_started_warning(sentry_init): + sentry_init(enable_tracing=True) + + tx = Transaction() + + with mock.patch("sentry_sdk.tracing.logger") as mock_logger: + with tx: + pass + + mock_logger.warning.assert_any_call( + "Transaction was entered without being started with sentry_sdk.start_transaction." + "The transaction will not be sent to Sentry. To fix, start the transaction by" + "passing it to sentry_sdk.start_transaction." + )