Skip to content

Commit 3735cb5

Browse files
authored
fix: Add basic breadth trimming to databags (getsentry#319)
* fix: Add basic breadth trimming to databags * fix: Also strip breadcrumbs * fix: Fix terrible bugs in _prepare_event * fix: Fix more bugs in handling of AnnotatedValue * fix: Lint
1 parent dc16b4b commit 3735cb5

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

sentry_sdk/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ def _prepare_event(
142142
# Postprocess the event here so that annotated types do
143143
# generally not surface in before_send
144144
if event is not None:
145+
event = convert_types(event)
145146
strip_event_mut(event)
146147
event = flatten_metadata(event)
147-
event = convert_types(event)
148148

149149
before_send = self.options["before_send"]
150150
if before_send is not None:

sentry_sdk/utils.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ def inner(obj):
709709
del meta[str(i)]
710710
return list_rv, (meta or None)
711711
if isinstance(obj, AnnotatedValue):
712-
return obj.value, {"": obj.metadata}
712+
return (inner(obj.value)[0], {"": obj.metadata})
713713
return obj, None
714714

715715
obj, meta = inner(obj)
@@ -727,6 +727,7 @@ def strip_event_mut(event):
727727
strip_stacktrace_mut(exception.get("stacktrace", None))
728728

729729
strip_request_mut(event.get("request", None))
730+
strip_breadcrumbs_mut(event.get("breadcrumbs", None))
730731

731732

732733
def strip_stacktrace_mut(stacktrace):
@@ -747,6 +748,14 @@ def strip_request_mut(request):
747748
request["data"] = strip_databag(data)
748749

749750

751+
def strip_breadcrumbs_mut(breadcrumbs):
752+
if not breadcrumbs:
753+
return
754+
755+
for i in range(len(breadcrumbs)):
756+
breadcrumbs[i] = strip_databag(breadcrumbs[i])
757+
758+
750759
def strip_frame_mut(frame):
751760
# type: (Dict[str, Any]) -> None
752761
if "vars" in frame:
@@ -769,32 +778,56 @@ def unmemoize(self, obj):
769778

770779
def convert_types(obj):
771780
# type: (Any) -> Any
781+
if obj is None:
782+
return None
772783
if obj is CYCLE_MARKER:
773784
return u"<cyclic>"
774785
if isinstance(obj, datetime):
775-
return obj.strftime("%Y-%m-%dT%H:%M:%SZ")
786+
return text_type(obj.strftime("%Y-%m-%dT%H:%M:%SZ"))
776787
if isinstance(obj, Mapping):
777788
return {k: convert_types(v) for k, v in obj.items()}
778789
if isinstance(obj, Sequence) and not isinstance(obj, (text_type, bytes)):
779790
return [convert_types(v) for v in obj]
791+
if isinstance(obj, AnnotatedValue):
792+
return AnnotatedValue(convert_types(obj.value), obj.metadata)
793+
780794
if not isinstance(obj, string_types + number_types):
781795
return safe_repr(obj)
782796
if isinstance(obj, bytes):
783797
return obj.decode("utf-8", "replace")
798+
784799
return obj
785800

786801

787-
def strip_databag(obj, remaining_depth=20):
788-
# type: (Any, int) -> Any
802+
def strip_databag(obj, remaining_depth=20, max_breadth=20):
803+
# type: (Any, int, int) -> Any
789804
assert not isinstance(obj, bytes), "bytes should have been normalized before"
790805
if remaining_depth <= 0:
791806
return AnnotatedValue(None, {"rem": [["!limit", "x"]]})
792807
if isinstance(obj, text_type):
793808
return strip_string(obj)
794809
if isinstance(obj, Mapping):
795-
return {k: strip_databag(v, remaining_depth - 1) for k, v in obj.items()}
810+
rv_dict = {} # type: Dict[Any, Any]
811+
for i, (k, v) in enumerate(obj.items()):
812+
if i >= max_breadth:
813+
return AnnotatedValue(rv_dict, {"len": max_breadth})
814+
rv_dict[k] = strip_databag(
815+
v, remaining_depth=remaining_depth - 1, max_breadth=max_breadth
816+
)
817+
818+
return rv_dict
796819
if isinstance(obj, Sequence):
797-
return [strip_databag(v, remaining_depth - 1) for v in obj]
820+
rv_list = [] # type: List[Any]
821+
for i, v in enumerate(obj):
822+
if i >= max_breadth:
823+
return AnnotatedValue(rv_list, {"len": max_breadth})
824+
rv_list.append(
825+
strip_databag(
826+
v, remaining_depth=remaining_depth - 1, max_breadth=max_breadth
827+
)
828+
)
829+
830+
return rv_list
798831
return obj
799832

800833

tests/test_client.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,21 @@ def test_databag_stripping(sentry_init, capture_events):
397397
assert len(json.dumps(event)) < 10000
398398

399399

400+
def test_databag_breadth_stripping(sentry_init, capture_events):
401+
sentry_init()
402+
events = capture_events()
403+
404+
try:
405+
a = ["a"] * 16000 # noqa
406+
1 / 0
407+
except Exception:
408+
capture_exception()
409+
410+
event, = events
411+
412+
assert len(json.dumps(event)) < 10000
413+
414+
400415
@pytest.mark.skipif(not HAS_CHAINED_EXCEPTIONS, reason="Only works on 3.3+")
401416
def test_chained_exceptions(sentry_init, capture_events):
402417
sentry_init()

0 commit comments

Comments
 (0)