Skip to content

Commit

Permalink
fix(aiohttp): Handle invalid responses (#3554)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
szokeasaurusrex committed Sep 23, 2024
1 parent 0ee7c50 commit 25ab10c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
12 changes: 11 additions & 1 deletion sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,17 @@ async def sentry_app_handle(self, request, *args, **kwargs):
# have no way to tell. Do not set span status.
reraise(*_capture_exception())

transaction.set_http_status(response.status)
try:
# A valid response handler will return a valid response with a status. But, if the handler
# returns an invalid response (e.g. None), the line below will raise an AttributeError.
# Even though this is likely invalid, we need to handle this case to ensure we don't break
# the application.
response_status = response.status
except AttributeError:
pass
else:
transaction.set_http_status(response_status)

return response

Application._handle = sentry_app_handle
Expand Down
21 changes: 21 additions & 0 deletions tests/integrations/aiohttp/test_aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,3 +596,24 @@ async def hello(request):
(event,) = events
assert event["contexts"]["trace"]["origin"] == "auto.http.aiohttp"
assert event["spans"][0]["origin"] == "auto.http.aiohttp"


@pytest.mark.asyncio
@pytest.mark.parametrize("invalid_response", (None, "invalid"))
async def test_invalid_response(
sentry_init, aiohttp_client, capture_events, invalid_response
):
sentry_init(integrations=[AioHttpIntegration()])

async def handler(_):
return invalid_response

app = web.Application()
app.router.add_get("/", handler)

client = await aiohttp_client(app)

# Invalid response should result on a ServerDisconnectedError in the client side, not an internal server error.
# Important to note that the ServerDisconnectedError indicates we have no error server-side.
with pytest.raises(ServerDisconnectedError):
await client.get("/")

0 comments on commit 25ab10c

Please sign in to comment.