Skip to content

Commit 25ab10c

Browse files
fix(aiohttp): Handle invalid responses (getsentry#3554)
If the request handler returns an invalid response (e.g. `None`), our SDK triggers an error because we try to access the invalid response's `status` attribute. Wrap this with a `try` block to handle the `AttributeError` and ensure the SDK does not break the app.
1 parent 0ee7c50 commit 25ab10c

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

sentry_sdk/integrations/aiohttp.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,17 @@ async def sentry_app_handle(self, request, *args, **kwargs):
139139
# have no way to tell. Do not set span status.
140140
reraise(*_capture_exception())
141141

142-
transaction.set_http_status(response.status)
142+
try:
143+
# A valid response handler will return a valid response with a status. But, if the handler
144+
# returns an invalid response (e.g. None), the line below will raise an AttributeError.
145+
# Even though this is likely invalid, we need to handle this case to ensure we don't break
146+
# the application.
147+
response_status = response.status
148+
except AttributeError:
149+
pass
150+
else:
151+
transaction.set_http_status(response_status)
152+
143153
return response
144154

145155
Application._handle = sentry_app_handle

tests/integrations/aiohttp/test_aiohttp.py

+21
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,24 @@ async def hello(request):
596596
(event,) = events
597597
assert event["contexts"]["trace"]["origin"] == "auto.http.aiohttp"
598598
assert event["spans"][0]["origin"] == "auto.http.aiohttp"
599+
600+
601+
@pytest.mark.asyncio
602+
@pytest.mark.parametrize("invalid_response", (None, "invalid"))
603+
async def test_invalid_response(
604+
sentry_init, aiohttp_client, capture_events, invalid_response
605+
):
606+
sentry_init(integrations=[AioHttpIntegration()])
607+
608+
async def handler(_):
609+
return invalid_response
610+
611+
app = web.Application()
612+
app.router.add_get("/", handler)
613+
614+
client = await aiohttp_client(app)
615+
616+
# Invalid response should result on a ServerDisconnectedError in the client side, not an internal server error.
617+
# Important to note that the ServerDisconnectedError indicates we have no error server-side.
618+
with pytest.raises(ServerDisconnectedError):
619+
await client.get("/")

0 commit comments

Comments
 (0)