diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 6c9ae117dc..8e4bf4981f 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -24,6 +24,7 @@ "ignore_errors": [], "request_bodies": "medium", "before_send": None, + "before_breadcrumb": None, "debug": False, } diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index ca991066ac..c66bb6be84 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -1,5 +1,6 @@ import sys import copy +from datetime import datetime from contextlib import contextmanager from ._compat import with_metaclass @@ -158,6 +159,16 @@ def add_breadcrumb(self, *args, **kwargs): crumb = args[0]() else: crumb = dict(*args, **kwargs) + if crumb is None: + return + + if crumb.get("timestamp") is None: + crumb["timestamp"] = datetime.utcnow() + if crumb.get("type") is None: + crumb["type"] = "default" + + if client.options["before_breadcrumb"] is not None: + crumb = client.options["before_breadcrumb"](crumb) if crumb is not None: scope._breadcrumbs.append(crumb) diff --git a/tests/test_basics.py b/tests/test_basics.py index 5bc8881dc6..5fa8bd03b2 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -1,4 +1,10 @@ -from sentry_sdk import configure_scope, capture_exception, last_event_id, Hub +from sentry_sdk import ( + configure_scope, + capture_exception, + add_breadcrumb, + last_event_id, + Hub, +) def test_processors(sentry_init, capture_events): @@ -38,3 +44,43 @@ def test_event_id(sentry_init, capture_events): assert event["event_id"] == event_id assert last_event_id() == event_id assert Hub.current.last_event_id() == event_id + + +def test_option_callback(sentry_init, capture_events): + drop_events = False + drop_breadcrumbs = False + + def before_send(event): + if not drop_events: + event["extra"] = {"foo": "bar"} + return event + + def before_breadcrumb(crumb): + if not drop_breadcrumbs: + crumb["data"] = {"foo": "bar"} + return crumb + + sentry_init(before_send=before_send, before_breadcrumb=before_breadcrumb) + events = capture_events() + + def do_this(): + add_breadcrumb(message="Hello") + try: + raise ValueError("aha!") + except Exception: + capture_exception() + + do_this() + drop_breadcrumbs = True + do_this() + drop_events = True + do_this() + + normal, no_crumbs = events + + assert normal["exception"]["values"][0]["type"] == "ValueError" + crumb, = normal["breadcrumbs"] + assert "timestamp" in crumb + assert crumb["message"] == "Hello" + assert crumb["data"] == {"foo": "bar"} + assert crumb["type"] == "default"