Skip to content
27 changes: 17 additions & 10 deletions sentry_sdk/integrations/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __call__(self, environ, start_response):

try:
rv = self.app(environ, start_response)
except Exception:
except BaseException:
reraise(*_capture_exception(hub))

return _ScopedResponse(hub, rv)
Expand Down Expand Up @@ -151,15 +151,22 @@ def get_client_ip(environ):

def _capture_exception(hub):
# type: (Hub) -> ExcInfo
exc_info = sys.exc_info()

# Check client here as it might have been unset while streaming response
if hub.client is not None:
exc_info = sys.exc_info()
event, hint = event_from_exception(
exc_info,
client_options=hub.client.options,
mechanism={"type": "wsgi", "handled": False},
)
hub.capture_event(event, hint=hint)
e = exc_info[1]

# SystemExit(0) is the only uncaught exception that is expected behavior
should_skip_capture = isinstance(e, SystemExit) and e.code in (0, None)
if not should_skip_capture:
event, hint = event_from_exception(
exc_info,
client_options=hub.client.options,
mechanism={"type": "wsgi", "handled": False},
)
hub.capture_event(event, hint=hint)

return exc_info


Expand All @@ -181,7 +188,7 @@ def __iter__(self):
chunk = next(iterator)
except StopIteration:
break
except Exception:
except BaseException:
reraise(*_capture_exception(self._hub))

yield chunk
Expand All @@ -192,7 +199,7 @@ def close(self):
self._response.close()
except AttributeError:
pass
except Exception:
except BaseException:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're missing an as e here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oof, thanks

reraise(*_capture_exception(self._hub))


Expand Down
77 changes: 77 additions & 0 deletions tests/integrations/wsgi/test_wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,28 @@ def app(environ, start_response):
return app


class IterableApp(object):
def __init__(self, iterable):
self.iterable = iterable

def __call__(self, environ, start_response):
return self.iterable


class ExitingIterable(object):
def __init__(self, exc_func):
self._exc_func = exc_func

def __iter__(self):
return self

def __next__(self):
raise self._exc_func()

def next(self):
return type(self).__next__(self)


def test_basic(sentry_init, crashing_app, capture_events):
sentry_init(send_default_pii=True)
app = SentryWsgiMiddleware(crashing_app)
Expand All @@ -30,3 +52,58 @@ def test_basic(sentry_init, crashing_app, capture_events):
"query_string": "",
"url": "http://localhost/",
}


@pytest.fixture(params=[0, None])
def test_systemexit_zero_is_ignored(sentry_init, capture_events, request):
zero_code = request.param
sentry_init(send_default_pii=True)
iterable = ExitingIterable(lambda: SystemExit(zero_code))
app = SentryWsgiMiddleware(IterableApp(iterable))
client = Client(app)
events = capture_events()

with pytest.raises(SystemExit):
client.get("/")

assert len(events) == 0


@pytest.fixture(params=["", "foo", 1, 2])
def test_systemexit_nonzero_is_captured(sentry_init, capture_events, request):
nonzero_code = request.param
sentry_init(send_default_pii=True)
iterable = ExitingIterable(lambda: SystemExit(nonzero_code))
app = SentryWsgiMiddleware(IterableApp(iterable))
client = Client(app)
events = capture_events()

with pytest.raises(SystemExit):
client.get("/")

event, = events

assert "exception" in event
exc = event["exception"]["values"][-1]
assert exc["type"] == "SystemExit"
assert exc["value"] == nonzero_code
assert event["level"] == "error"


def test_keyboard_interrupt_is_captured(sentry_init, capture_events):
sentry_init(send_default_pii=True)
iterable = ExitingIterable(lambda: KeyboardInterrupt())
app = SentryWsgiMiddleware(IterableApp(iterable))
client = Client(app)
events = capture_events()

with pytest.raises(KeyboardInterrupt):
client.get("/")

event, = events

assert "exception" in event
exc = event["exception"]["values"][-1]
assert exc["type"] == "KeyboardInterrupt"
assert exc["value"] == ""
assert event["level"] == "error"