Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inappropriate "break in finally" #10434

Merged
merged 12 commits into from
Feb 17, 2025
2 changes: 2 additions & 0 deletions CHANGES/10434.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Avoid break statement inside the finally block in :py:class:`~aiohttp.web.RequestHandler`
-- by :user:`Cycloctane`.
30 changes: 17 additions & 13 deletions aiohttp/web_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,26 +633,30 @@ async def start(self) -> None:

except asyncio.CancelledError:
self.log_debug("Ignored premature client disconnection")
self.force_close()
raise
except Exception as exc:
self.log_exception("Unhandled exception", exc_info=exc)
self.force_close()
except BaseException:
self.force_close()
raise
else:
if self._keepalive and not self._close:
# start keep-alive timer
if keepalive_timeout is not None:
now = loop.time()
close_time = now + keepalive_timeout
self._next_keepalive_close_time = close_time
if self._keepalive_handle is None:
self._keepalive_handle = loop.call_at(
close_time, self._process_keepalive
)
else:
break
finally:
if self.transport is None and resp is not None:
self.log_debug("Ignored premature client disconnection.")
elif not self._force_close:
if self._keepalive and not self._close:
# start keep-alive timer
if keepalive_timeout is not None:
now = loop.time()
close_time = now + keepalive_timeout
self._next_keepalive_close_time = close_time
if self._keepalive_handle is None:
self._keepalive_handle = loop.call_at(
close_time, self._process_keepalive
)
else:
break

# remove handler, close transport if no handlers left
if not self._force_close:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_web_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,24 @@ async def handler(request: web.BaseRequest) -> NoReturn:
logger.debug.assert_called_with("Ignored premature client disconnection")


async def test_raw_server_do_not_swallow_base_exceptions(
aiohttp_raw_server: AiohttpRawServer, aiohttp_client: AiohttpClient
) -> None:
class UnexpectedException(BaseException):
pass

async def handler(request: web.BaseRequest) -> NoReturn:
raise UnexpectedException()

loop = asyncio.get_event_loop()
loop.set_debug(True)
server = await aiohttp_raw_server(handler)
cli = await aiohttp_client(server)

with pytest.raises(client.ServerDisconnectedError):
await cli.get("/path/to", timeout=client.ClientTimeout(10))


async def test_raw_server_cancelled_in_write_eof(
aiohttp_raw_server: AiohttpRawServer, aiohttp_client: AiohttpClient
) -> None:
Expand Down
Loading