Skip to content

Commit 99900d1

Browse files
shenekuntitaker
authored andcommitted
fix: RuntimeError: dictionary changed size during iteration can be raised in extract_locals phase (getsentry#298)
* affects only python3 because items() in python3 doesn't return list * note that this situation is actually a simplified example how environ is treated in Bottle framework
1 parent 5ecc098 commit 99900d1

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

sentry_sdk/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ def object_to_json(obj, remaining_depth=4, memo=None):
376376
safe_str(k): object_to_json(
377377
v, remaining_depth=remaining_depth - 1, memo=memo
378378
)
379-
for k, v in obj.items()
379+
for k, v in list(obj.items())
380380
}
381381

382382
return safe_repr(obj)

tests/integrations/wsgi/test_wsgi.py

+32
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@ def app(environ, start_response):
1212
return app
1313

1414

15+
@pytest.fixture
16+
def crashing_env_modifing_app():
17+
class TooSmartClass(object):
18+
def __init__(self, environ):
19+
self.environ = environ
20+
21+
def __repr__(self):
22+
if "my_representation" in self.environ:
23+
return self.environ["my_representation"]
24+
25+
self.environ["my_representation"] = "<This is me>"
26+
return self.environ["my_representation"]
27+
28+
def app(environ, start_response):
29+
environ["tsc"] = TooSmartClass(environ)
30+
1 / 0
31+
32+
return app
33+
34+
1535
def test_basic(sentry_init, crashing_app, capture_events):
1636
sentry_init(send_default_pii=True)
1737
app = SentryWsgiMiddleware(crashing_app)
@@ -30,3 +50,15 @@ def test_basic(sentry_init, crashing_app, capture_events):
3050
"query_string": "",
3151
"url": "http://localhost/",
3252
}
53+
54+
55+
def test_env_modifing_app(sentry_init, crashing_env_modifing_app, capture_events):
56+
sentry_init(send_default_pii=True)
57+
app = SentryWsgiMiddleware(crashing_env_modifing_app)
58+
client = Client(app)
59+
events = capture_events()
60+
61+
with pytest.raises(ZeroDivisionError):
62+
client.get("/")
63+
64+
assert len(events) == 1 # only one exception is raised

0 commit comments

Comments
 (0)