Вызываемый ASGI возвращается без начального ответа

#fastapi #uvicorn #asgi

Вопрос:

fastAPI, над которым я работаю, не возвращает трассировку всякий раз, когда запрос не удался, вместо этого он возвращает 500 внутренних ошибок сервера с ошибкой :

 ERROR:    ASGI callable returned without starting response.
2021-05-14 16:12:08 - uvicorn.error:409 - ERROR - ASGI callable returned without starting response.
 

Кто-нибудь сталкивался с этой проблемой раньше и знает, как ее решить ?

Комментарии:

1. можете ли вы включить код api конечной точки, который вы пытаетесь вызвать? а также заголовки запроса/ответа с curl -Lv http://<yoursite>/ ? А также используемая версия fastapi, uvicorn и python?

2. также попробуйте uvicorn your.app:app --log-level debug добавить отладку уровня журнала в uvicorn, какие-либо изменения?

3. @jmunsch это довольно большая база кода, поэтому я не включил код в вопрос. Для версий fastapi==0.63.0, uvicorn==0.13.3, python 3.8

4. @jmunsch У меня установлен уровень ведения журнала для отладки. Это приведет к выходу из системы отладочной информации. Тем не менее, я хочу распечатывать обратную трассировку всякий раз, когда сервер выходил из строя. Вроде как невозможно выйти из системы со всеми возможными ошибками.

5. @jmunsch Я выяснил причину, по которой fastAPI не возвращает трассировку, но общую ошибку. Это было связано с промежуточным программным обеспечением, которое я создал для этого API. Промежуточное программное обеспечение подкласса из PrometheusMiddleware, добавьте дополнительную метку в метрики Prometheus и добавьте атрибут в область http — запроса. Я не уверен, почему это вызвало проблему с тем, что fastAPI не может правильно возвращать трассировку.

Ответ №1:

Моя проблема была вызвана настройкой промежуточного программного обеспечения. Мне удалось обновить промежуточное программное обеспечение и устранить эту проблему.

Ответ №2:

Скорее __ call __ всего, метод вашего промежуточного программного обеспечения работает не очень хорошо. Я бы посоветовал проверить сборку в промежуточном программном обеспечении и сравнить ее с вашей. Например:

     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
    if scope["type"] != "http":
        await self.app(scope, receive, send)
        return

    request = Request(scope, receive=receive)
    response = await self.dispatch_func(request, self.call_next)
    await response(scope, receive, send)