Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

db session middleware with custom exception middleware raises AnyIO EndOfSteam when client closes early #4544

Closed
9 tasks done
s-quinn opened this issue Feb 9, 2022 · 5 comments

Comments

@s-quinn
Copy link

s-quinn commented Feb 9, 2022

First Check

  • I added a very descriptive title to this issue.
  • I used the GitHub search to find a similar issue and didn't find it.
  • I searched the FastAPI documentation, with the integrated search.
  • I already searched in Google "How to X in FastAPI" and didn't find any information.
  • I already read and followed all the tutorial in the docs and didn't find an answer.
  • I already checked if it is not related to FastAPI but to Pydantic.
  • I already checked if it is not related to FastAPI but to Swagger UI.
  • I already checked if it is not related to FastAPI but to ReDoc.

Commit to Help

  • I commit to help with one of those options 👆

Example Code

import time
from typing import Callable, Awaitable

import uvicorn
from fastapi import FastAPI
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
from starlette.requests import Request
from starlette.responses import Response



SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
    SQLALCHEMY_DATABASE_URL
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base(bind=engine)

app = FastAPI()

class ExceptionHandlerMiddleware:
    async def __call__(
        self,
        request: Request,
        call_next: Callable[[Request], Awaitable[Response]],
    ) -> Response:
        try:
            return await call_next(request)
        except Exception as exc:
            print(exc)


app.middleware('http')(ExceptionHandlerMiddleware())


@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
    response = Response("Internal server error", status_code=500)
    try:
        request.state.db = SessionLocal()
        response = await call_next(request)
    finally:
        request.state.db.close()
    return response


@app.get('/')
def test():
    time.sleep(2)
    return {'message': 'hello'}


if __name__ == '__main__':
    uvicorn.run(
        'example:app',
        reload=True,
    )

Description

We are using the db session middleware exactly as described here in combination with a custom http exception middleware. When a client is disconnecting from us early we get spammed with a bunch of No response returned errors from starlette.

How to reproduce:

Open browser and call the endpoint /
Close the window before the request completes.
You will see that AnyIO raises a EndOfStream error which ends up being propogated as a Runtime Error with the message as No response returned

Operating System

Linux, macOS

Operating System Details

No response

FastAPI Version

0.73.0

Python Version

Python 3.9.6

Additional Context

SQLAlchemy==1.4.31

@s-quinn s-quinn added the question Question or problem label Feb 9, 2022
@teamhide
Copy link

teamhide commented Apr 1, 2022

+1

@wwarne
Copy link

wwarne commented Apr 2, 2022

+1 too.

@guya-pecan
Copy link

+1 as well

@leydenberg
Copy link

+1 :(

@robotadam
Copy link

robotadam commented Oct 13, 2022

I did some tests on this after Starlette merged encode/starlette#1715, which contains further fixes for this. It resolved the issues in my fastapi app with early disconnection, so I'm feeling positive that the pending update will be the solution for this bug. #5471

Repository owner locked and limited conversation to collaborators Feb 28, 2023
@tiangolo tiangolo converted this issue into discussion #8582 Feb 28, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

7 participants