From 525215af5e2c8d33dc4c27f0152ceebcf3196f91 Mon Sep 17 00:00:00 2001 From: florimondmanca Date: Wed, 11 Aug 2021 12:15:30 +0200 Subject: [PATCH] Prevent ExceptionGroup in error views under a BaseHTTPMiddleware --- starlette/middleware/base.py | 5 +++++ tests/middleware/test_base.py | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/starlette/middleware/base.py b/starlette/middleware/base.py index 77ba669251..6b3bb3b189 100644 --- a/starlette/middleware/base.py +++ b/starlette/middleware/base.py @@ -1,3 +1,4 @@ +import itertools import typing import anyio @@ -34,6 +35,10 @@ async def coro() -> None: try: message = await recv_stream.receive() except anyio.EndOfStream: + # HACK: give anyio a chance to surface any app exception first, + # in order to avoid an `anyio.ExceptionGroup`. + # See #1255. + await anyio.lowlevel.checkpoint() raise RuntimeError("No response returned.") assert message["type"] == "http.response.start" diff --git a/tests/middleware/test_base.py b/tests/middleware/test_base.py index 8a8df4ea66..c6bfd49fc8 100644 --- a/tests/middleware/test_base.py +++ b/tests/middleware/test_base.py @@ -25,7 +25,7 @@ def homepage(request): @app.route("/exc") def exc(request): - raise Exception() + raise Exception("Exc") @app.route("/no-response") @@ -52,8 +52,9 @@ def test_custom_middleware(test_client_factory): response = client.get("/") assert response.headers["Custom-Header"] == "Example" - with pytest.raises(Exception): + with pytest.raises(Exception) as ctx: response = client.get("/exc") + assert str(ctx.value) == "Exc" with pytest.raises(RuntimeError): response = client.get("/no-response")