Skip to content

Commit e1791a9

Browse files
committed
Do not serialize mappings with custom __repr__ as dict-s
Fixes #1296
1 parent 6d89f4f commit e1791a9

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

sentry_sdk/serializer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,10 @@ def _serialize_node_impl(
288288
else safe_repr(obj)
289289
)
290290

291-
elif isinstance(obj, Mapping):
291+
elif isinstance(obj, Mapping) and type(obj).__repr__ in (
292+
object.__repr__,
293+
dict.__repr__,
294+
):
292295
# Create temporary copy here to avoid calling too much code that
293296
# might mutate our dictionary while we're still iterating over it.
294297
obj = dict(iteritems(obj))

tests/test_client.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,8 @@ def test_chained_exceptions(sentry_init, capture_events):
646646

647647

648648
@pytest.mark.tests_internal_exceptions
649-
def test_broken_mapping(sentry_init, capture_events):
649+
@pytest.mark.parametrize("with_custom_repr", [False, True])
650+
def test_broken_mapping(sentry_init, capture_events, with_custom_repr):
650651
sentry_init()
651652
events = capture_events()
652653

@@ -660,8 +661,10 @@ def broken(self, *args, **kwargs):
660661
__iter__ = broken
661662
__len__ = broken
662663

663-
def __repr__(self):
664-
return "broken"
664+
if with_custom_repr:
665+
666+
def __repr__(self):
667+
return "still works"
665668

666669
try:
667670
a = C() # noqa
@@ -670,9 +673,13 @@ def __repr__(self):
670673
capture_exception()
671674

672675
(event,) = events
676+
if with_custom_repr:
677+
valid_repr = "still works"
678+
else:
679+
valid_repr = "<failed to serialize, use init(debug=True) to see error logs>"
673680
assert (
674681
event["exception"]["values"][0]["stacktrace"]["frames"][0]["vars"]["a"]
675-
== "<failed to serialize, use init(debug=True) to see error logs>"
682+
== valid_repr
676683
)
677684

678685

tests/test_serializer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,12 @@ def test_bytes_serialization_repr(message_normalizer):
6464
def test_serialize_sets(extra_normalizer):
6565
result = extra_normalizer({1, 2, 3})
6666
assert result == [1, 2, 3]
67+
68+
69+
def test_serialize_custom_mapping(extra_normalizer):
70+
class CustomReprDict(dict):
71+
def __repr__(self):
72+
return "custom!"
73+
74+
result = extra_normalizer(CustomReprDict(one=1, two=2))
75+
assert result == "custom!"

0 commit comments

Comments
 (0)