Skip to content

Commit

Permalink
Unwrap view errors occurring under a BaseHTTPMiddleware
Browse files Browse the repository at this point in the history
  • Loading branch information
florimondmanca committed Aug 11, 2021
1 parent e45c579 commit ed4246f
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions starlette/middleware/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async def coro() -> None:
try:
message = await recv_stream.receive()
except anyio.EndOfStream:
raise RuntimeError("No response returned.")
raise RuntimeError("No response returned.") from None

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

Expand All @@ -50,11 +50,28 @@ async def body_stream() -> typing.AsyncGenerator[bytes, None]:
response.raw_headers = message["headers"]
return response

async with anyio.create_task_group() as task_group:
request = Request(scope, receive=receive)
response = await self.dispatch_func(request, call_next)
await response(scope, receive, send)
task_group.cancel_scope.cancel()
try:
async with anyio.create_task_group() as task_group:
request = Request(scope, receive=receive)
response = await self.dispatch_func(request, call_next)
await response(scope, receive, send)
task_group.cancel_scope.cancel()
except anyio.ExceptionGroup as exc_group:
first, *rest = exc_group.exceptions
if str(first) == "No response returned.":
# "No response returned", and we got an exception group, meaning
# the app raised an exception.
# Raise the latter in priority, so that we:
# a/ match the behavior before 0.16.0 (see regression #1255).
# b/ keep `anyio` as an implementation detail internally.
assert len(rest) == 1
(exc,) = rest
raise exc from None
else:
# User may have used `anyio` directly and triggered an
# `ExceptionGroup` which they may want to manage themselves.
# Let it be.
raise

async def dispatch(
self, request: Request, call_next: RequestResponseEndpoint
Expand Down

0 comments on commit ed4246f

Please sign in to comment.