MCPcopy
hub / github.com/encode/starlette / call_next

Method call_next

starlette/middleware/base.py:112–187  ·  view source on GitHub ↗
(request: Request)

Source from the content-addressed store, hash-verified

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.")

Callers

nothing calls this directly

Calls 3

_StreamingResponseClass · 0.85
receiveMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected