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.
		
		
		
		
		
			
		
			
				
					
					
						
							29 lines
						
					
					
						
							1.2 KiB
						
					
					
				
			
		
		
	
	
							29 lines
						
					
					
						
							1.2 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:
 | 
						|
        if AsyncExitStack:
 | 
						|
            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
 | 
						|
        else:
 | 
						|
            await self.app(scope, receive, send)  # pragma: no cover
 |