(self, scope: Scope, receive: Receive, send: Send)
| 147 | self.debug = debug |
| 148 | |
| 149 | async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: |
| 150 | if scope[class="st">"type"] != class="st">"http": |
| 151 | await self.app(scope, receive, send) |
| 152 | return |
| 153 | |
| 154 | response_started = False |
| 155 | |
| 156 | async def _send(message: Message) -> None: |
| 157 | nonlocal response_started, send |
| 158 | |
| 159 | if message[class="st">"type"] == class="st">"http.response.start": |
| 160 | response_started = True |
| 161 | await send(message) |
| 162 | |
| 163 | try: |
| 164 | await self.app(scope, receive, _send) |
| 165 | except Exception as exc: |
| 166 | request = Request(scope) |
| 167 | if self.debug: |
| 168 | class="cm"># In debug mode, return traceback responses. |
| 169 | response = self.debug_response(request, exc) |
| 170 | elif self.handler is None: |
| 171 | class="cm"># Use our default 500 error handler. |
| 172 | response = self.error_response(request, exc) |
| 173 | else: |
| 174 | class="cm"># Use an installed 500 error handler. |
| 175 | if is_async_callable(self.handler): |
| 176 | response = await self.handler(request, exc) class="cm"># type: ignore[assignment, arg-type] |
| 177 | else: |
| 178 | response = await run_in_threadpool(self.handler, request, exc) class="cm"># type: ignore[arg-type] |
| 179 | |
| 180 | if not response_started: |
| 181 | await response(scope, receive, send) |
| 182 | |
| 183 | class="cm"># We always continue to raise the exception. |
| 184 | class="cm"># This allows servers to log the error, or allows test clients |
| 185 | class="cm"># to optionally raise the error within the test case. |
| 186 | raise exc |
| 187 | |
| 188 | def format_line(self, index: int, line: str, frame_lineno: int, frame_index: int) -> str: |
| 189 | values = { |
nothing calls this directly
no test coverage detected