(scope: Scope, receive: Receive, send: Send)
| 29 | exception_handlers, status_handlers = {}, {} |
| 30 | |
| 31 | async def wrapped_app(scope: Scope, receive: Receive, send: Send) -> None: |
| 32 | response_started = False |
| 33 | |
| 34 | async def sender(message: Message) -> None: |
| 35 | nonlocal response_started |
| 36 | |
| 37 | if message["type"] == "http.response.start": |
| 38 | response_started = True |
| 39 | await send(message) |
| 40 | |
| 41 | try: |
| 42 | await app(scope, receive, sender) |
| 43 | except Exception as exc: |
| 44 | handler = None |
| 45 | |
| 46 | if isinstance(exc, HTTPException): |
| 47 | handler = status_handlers.get(exc.status_code) |
| 48 | |
| 49 | if handler is None: |
| 50 | handler = _lookup_exception_handler(exception_handlers, exc) |
| 51 | |
| 52 | if handler is None: |
| 53 | raise exc |
| 54 | |
| 55 | if response_started: |
| 56 | raise RuntimeError("Caught handled exception, but response already started.") from exc |
| 57 | |
| 58 | if is_async_callable(handler): |
| 59 | response = await handler(conn, exc) # type: ignore[arg-type] |
| 60 | else: |
| 61 | response = await run_in_threadpool(handler, conn, exc) # type: ignore[arg-type] |
| 62 | if response is not None: |
| 63 | await response(scope, receive, sender) |
| 64 | |
| 65 | return wrapped_app |
nothing calls this directly
no test coverage detected