From 97ae8e2cfeb9a11634c35650ba1ed6a61e844bdd Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 15:40:11 +0100 Subject: [PATCH 1/7] Reset DedupeIntegrations last-seen if before_send dropped the event --- sentry_sdk/client.py | 4 ++++ sentry_sdk/integrations/dedupe.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 5bbf919c02..889cb38f7f 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -606,6 +606,10 @@ def _prepare_event( self.transport.record_lost_event( "before_send", data_category="error" ) + from sentry_sdk.integrations.dedupe import DedupeIntegration + + DedupeIntegration.reset_last_seen() + event = new_event before_send_transaction = self.options["before_send_transaction"] diff --git a/sentry_sdk/integrations/dedupe.py b/sentry_sdk/integrations/dedupe.py index be6d9311a3..5cbb5b94c4 100644 --- a/sentry_sdk/integrations/dedupe.py +++ b/sentry_sdk/integrations/dedupe.py @@ -40,3 +40,11 @@ def processor(event, hint): return None integration._last_seen.set(exc) return event + + @staticmethod + def reset_last_seen(): + integration = sentry_sdk.get_client().get_integration(DedupeIntegration) + if integration is None: + return + + integration._last_seen.set(None) From 6495a08da6bd586ea79445fbdb4c497811c9c4b8 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 15:48:10 +0100 Subject: [PATCH 2/7] add missing type --- sentry_sdk/integrations/dedupe.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sentry_sdk/integrations/dedupe.py b/sentry_sdk/integrations/dedupe.py index 5cbb5b94c4..a115e35292 100644 --- a/sentry_sdk/integrations/dedupe.py +++ b/sentry_sdk/integrations/dedupe.py @@ -43,6 +43,7 @@ def processor(event, hint): @staticmethod def reset_last_seen(): + # type: () -> None integration = sentry_sdk.get_client().get_integration(DedupeIntegration) if integration is None: return From 4dab8a2aa99898418eb9fe943669e07ab98b33ca Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 16:02:31 +0100 Subject: [PATCH 3/7] test and comment --- tests/test_basics.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/test_basics.py b/tests/test_basics.py index ad20bb9fd5..7bfe05a216 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -710,6 +710,40 @@ def test_dedupe_event_processor_drop_records_client_report( assert lost_event_call == ("event_processor", "error", None, 1) +def test_dedupe_doesnt_take_into_account_dropped_exception(sentry_init, capture_events): + # Two exceptions happen one after another. The first one is dropped in the + # user's before_send. The second one isn't. + # Originally, DedupeIntegration would drop the second exception. This test + # is making sure that that is no longer the case -- i.e., DedupeIntegration + # doesn't consider exceptions dropped in before_send. + count = 0 + + def before_send(event, hint): + nonlocal count + count += 1 + if count == 1: + return None + return event + + sentry_init(before_send=before_send) + events = capture_events() + + for _ in range(2): + # The first ValueError will be dropped by before_send. The second + # ValueError will be accepted by before_send, and should be sent to + # Sentry. + try: + raise ValueError("aha!") + except Exception: + try: + capture_exception() + reraise(*sys.exc_info()) + except Exception: + capture_exception() + + assert len(events) == 2 + + def test_event_processor_drop_records_client_report( sentry_init, capture_events, capture_record_lost_event_calls ): From 05618a3830b8ab2d366f2b52dd17f1ed66deab4b Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 16:09:20 +0100 Subject: [PATCH 4/7] fix test --- tests/test_basics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_basics.py b/tests/test_basics.py index 7bfe05a216..9491192ea8 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -741,7 +741,7 @@ def before_send(event, hint): except Exception: capture_exception() - assert len(events) == 2 + assert len(events) == 1 def test_event_processor_drop_records_client_report( From 47ef906627579a3c26b65b6e82aa40d488831ac8 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 16:10:41 +0100 Subject: [PATCH 5/7] import --- sentry_sdk/client.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 889cb38f7f..6ff72c509d 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -37,6 +37,7 @@ ClientConstructor, ) from sentry_sdk.integrations import _DEFAULT_INTEGRATIONS, setup_integrations +from sentry_sdk.integrations.dedupe import DedupeIntegration from sentry_sdk.sessions import SessionFlusher from sentry_sdk.envelope import Envelope from sentry_sdk.profiler.continuous_profiler import setup_continuous_profiler @@ -606,8 +607,8 @@ def _prepare_event( self.transport.record_lost_event( "before_send", data_category="error" ) - from sentry_sdk.integrations.dedupe import DedupeIntegration + # XXX: Should only reset if this is an exception DedupeIntegration.reset_last_seen() event = new_event From 31c888676e1a3bea68270000e76f2b315053188d Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 16:20:13 +0100 Subject: [PATCH 6/7] fix --- tests/test_basics.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_basics.py b/tests/test_basics.py index 9491192ea8..d1c3bce2be 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -728,18 +728,15 @@ def before_send(event, hint): sentry_init(before_send=before_send) events = capture_events() + exc = ValueError("aha!") for _ in range(2): # The first ValueError will be dropped by before_send. The second # ValueError will be accepted by before_send, and should be sent to # Sentry. try: - raise ValueError("aha!") + raise exc except Exception: - try: - capture_exception() - reraise(*sys.exc_info()) - except Exception: - capture_exception() + capture_exception() assert len(events) == 1 From 99850052cc5c4596563ab67e7d760e974072f482 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 17 Mar 2025 16:26:47 +0100 Subject: [PATCH 7/7] comment --- sentry_sdk/client.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 6ff72c509d..0f97394561 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -608,8 +608,12 @@ def _prepare_event( "before_send", data_category="error" ) - # XXX: Should only reset if this is an exception - DedupeIntegration.reset_last_seen() + # If this is an exception, reset the DedupeIntegration. It still + # remembers the dropped exception as the last exception, meaning + # that if the same exception happens again and is not dropped + # in before_send, it'd get dropped by DedupeIntegration. + if event.get("exception"): + DedupeIntegration.reset_last_seen() event = new_event