(request: Request)
| 110 | exception_already_raised = False |
| 111 | |
| 112 | async def call_next(request: Request) -> Response: |
| 113 | async def receive_or_disconnect() -> Message: |
| 114 | if response_sent.is_set(): |
| 115 | return {"type": "http.disconnect"} |
| 116 | |
| 117 | async with anyio.create_task_group() as task_group: |
| 118 | |
| 119 | async def wrap(func: Callable[[], Awaitable[T]]) -> T: |
| 120 | result = await func() |
| 121 | task_group.cancel_scope.cancel() |
| 122 | return result |
| 123 | |
| 124 | task_group.start_soon(wrap, response_sent.wait) |
| 125 | message = await wrap(wrapped_receive) |
| 126 | |
| 127 | if response_sent.is_set(): |
| 128 | return {"type": "http.disconnect"} |
| 129 | |
| 130 | return message |
| 131 | |
| 132 | async def send_no_error(message: Message) -> None: |
| 133 | try: |
| 134 | await send_stream.send(message) |
| 135 | except anyio.BrokenResourceError: |
| 136 | # recv_stream has been closed, i.e. response_sent has been set. |
| 137 | return |
| 138 | |
| 139 | async def coro() -> None: |
| 140 | nonlocal app_exc |
| 141 | |
| 142 | with send_stream: |
| 143 | try: |
| 144 | await self.app(scope, receive_or_disconnect, send_no_error) |
| 145 | except Exception as exc: |
| 146 | app_exc = exc |
| 147 | |
| 148 | task_group.start_soon(coro) |
| 149 | |
| 150 | try: |
| 151 | message = await recv_stream.receive() |
| 152 | info = message.get("info", None) |
| 153 | if message["type"] == "http.response.debug" and info is not None: |
| 154 | message = await recv_stream.receive() |
| 155 | except anyio.EndOfStream: |
| 156 | if app_exc is not None: |
| 157 | nonlocal exception_already_raised |
| 158 | exception_already_raised = True |
| 159 | # Prevent `anyio.EndOfStream` from polluting app exception context. |
| 160 | # If both cause and context are None then the context is suppressed |
| 161 | # and `anyio.EndOfStream` is not present in the exception traceback. |
| 162 | # If exception cause is not None then it is propagated with |
| 163 | # reraising here. |
| 164 | # If exception has no cause but has context set then the context is |
| 165 | # propagated as a cause with the reraise. This is necessary in order |
| 166 | # to prevent `anyio.EndOfStream` from polluting the exception |
| 167 | # context. |
| 168 | raise app_exc from app_exc.__cause__ or app_exc.__context__ |
| 169 | raise RuntimeError("No response returned.") |
nothing calls this directly
no test coverage detected