Skip to content

Commit 6c9bc55

Browse files
Prevent anyio.ExceptionGroup in error views under a BaseHTTPMiddleware (#1262)
* Prevent ExceptionGroup in error views under a BaseHTTPMiddleware * Apply suggestion from @uSpike Co-authored-by: euri10 <benoit.barthelet@gmail.com>
1 parent d87c93e commit 6c9bc55

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

starlette/middleware/base.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,25 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
2323
return
2424

2525
async def call_next(request: Request) -> Response:
26+
app_exc: typing.Optional[Exception] = None
2627
send_stream, recv_stream = anyio.create_memory_object_stream()
2728

2829
async def coro() -> None:
30+
nonlocal app_exc
31+
2932
async with send_stream:
30-
await self.app(scope, request.receive, send_stream.send)
33+
try:
34+
await self.app(scope, request.receive, send_stream.send)
35+
except Exception as exc:
36+
app_exc = exc
3137

3238
task_group.start_soon(coro)
3339

3440
try:
3541
message = await recv_stream.receive()
3642
except anyio.EndOfStream:
43+
if app_exc is not None:
44+
raise app_exc
3745
raise RuntimeError("No response returned.")
3846

3947
assert message["type"] == "http.response.start"

tests/middleware/test_base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def homepage(request):
2525

2626
@app.route("/exc")
2727
def exc(request):
28-
raise Exception()
28+
raise Exception("Exc")
2929

3030

3131
@app.route("/no-response")
@@ -52,8 +52,9 @@ def test_custom_middleware(test_client_factory):
5252
response = client.get("/")
5353
assert response.headers["Custom-Header"] == "Example"
5454

55-
with pytest.raises(Exception):
55+
with pytest.raises(Exception) as ctx:
5656
response = client.get("/exc")
57+
assert str(ctx.value) == "Exc"
5758

5859
with pytest.raises(RuntimeError):
5960
response = client.get("/no-response")

0 commit comments

Comments
 (0)