Skip to content

Commit c289264

Browse files
committed
fix(integrations): Don't capture StopIteration in SentryWsgiMiddleware
Currently Sentry will emit an unhandled exception for StopIteration. However, when running certain combinations of libraries with gunicorn and sync workers (eg: python-socketio) the StopIteration exception is actually expected. To workaround this issue, don't capture this exception when using this middleware with gunicorn and just reraise it.
1 parent 00f8140 commit c289264

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

sentry_sdk/integrations/wsgi.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ def __call__(self, environ, start_response):
134134
_sentry_start_response, start_response, transaction
135135
),
136136
)
137+
except StopIteration:
138+
if "gunicorn" in environ.get("SERVER_SOFTWARE", ""):
139+
raise
140+
else:
141+
reraise(*_capture_exception())
137142
except BaseException:
138143
reraise(*_capture_exception())
139144
finally:

tests/integrations/wsgi/test_wsgi.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from unittest import mock
33

44
import pytest
5-
from werkzeug.test import Client
5+
from werkzeug.test import Client, EnvironBuilder
66

77
import sentry_sdk
88
from sentry_sdk import capture_message
@@ -135,6 +135,49 @@ def test_keyboard_interrupt_is_captured(sentry_init, capture_events):
135135
assert event["level"] == "error"
136136

137137

138+
def test_stopiteration_is_not_ignored(sentry_init, capture_events, request):
139+
sentry_init(send_default_pii=True)
140+
141+
def exiting_app(environ, start_response):
142+
raise StopIteration()
143+
144+
app = SentryWsgiMiddleware(exiting_app)
145+
client = Client(app)
146+
events = capture_events()
147+
148+
with pytest.raises(StopIteration):
149+
client.get("/")
150+
151+
(event,) = events
152+
153+
assert "exception" in event
154+
exc = event["exception"]["values"][-1]
155+
assert exc["type"] == "StopIteration"
156+
assert exc["value"] == ""
157+
assert event["level"] == "error"
158+
159+
160+
def test_stopiteration_is_ignored_for_gunicorn(sentry_init, capture_events, request):
161+
sentry_init(send_default_pii=True)
162+
163+
def exiting_app(environ, start_response):
164+
raise StopIteration()
165+
166+
app = SentryWsgiMiddleware(exiting_app)
167+
client = Client(app)
168+
events = capture_events()
169+
170+
with pytest.raises(StopIteration):
171+
builder = EnvironBuilder(
172+
"/", environ_base={"SERVER_SOFTWARE": "gunicorn/23.0.0"}
173+
)
174+
request = builder.get_request()
175+
builder.close()
176+
client.open(request)
177+
178+
assert len(events) == 0
179+
180+
138181
def test_transaction_with_error(
139182
sentry_init, crashing_app, capture_events, DictionaryContaining # noqa:N803
140183
):

0 commit comments

Comments
 (0)