You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
25 lines
1.0 KiB
25 lines
1.0 KiB
from typing import Optional |
|
|
|
from fastapi.concurrency import AsyncExitStack |
|
from starlette.types import ASGIApp, Receive, Scope, Send |
|
|
|
|
|
class AsyncExitStackMiddleware: |
|
def __init__(self, app: ASGIApp, context_name: str = "fastapi_astack") -> None: |
|
self.app = app |
|
self.context_name = context_name |
|
|
|
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: |
|
dependency_exception: Optional[Exception] = None |
|
async with AsyncExitStack() as stack: |
|
scope[self.context_name] = stack |
|
try: |
|
await self.app(scope, receive, send) |
|
except Exception as e: |
|
dependency_exception = e |
|
raise e |
|
if dependency_exception: |
|
# This exception was possibly handled by the dependency but it should |
|
# still bubble up so that the ServerErrorMiddleware can return a 500 |
|
# or the ExceptionMiddleware can catch and handle any other exceptions |
|
raise dependency_exception
|
|
|