-
-
Notifications
You must be signed in to change notification settings - Fork 24
-
-
Notifications
You must be signed in to change notification settings - Fork 24
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
ContextDoesNotExistError on FastAPI Custom Exception Handler #74
Comments
How exactly are you "try[ing] to access context inside the custom exception handler"? |
@hhamana thank you for your reply. This is an example, which reproduce my issue. from fastapi import FastAPI
from fastapi.responses import JSONResponse
from typing import Dict, Any
from fastapi import Request
from starlette_context import context
from fastapi import FastAPI, Depends, Header
from starlette_context import request_cycle_context
async def my_context_dependency(x_plt_user_id: str = Header(None)) -> Any:
data = {"user-id": x_plt_user_id}
with request_cycle_context(data):
# yield allows it to pass along to the rest of the request
yield
app = FastAPI(
dependencies=[Depends(my_context_dependency)],
title="Test App",
)
@app.exception_handler(Exception)
async def unicorn_exception_handler(request: Request, exc: Exception) -> JSONResponse:
user_id = context.get("user-id", default=None)
print(user_id)
return JSONResponse(
status_code=400,
content={"message": "Bad Request"},
)
@app.get("/")
async def root() -> Dict[str, str]:
raise Exception("Test")
return {"message": "Hello World"}
if __name__ == "__main__":
# Use this for debugging purposes only
import uvicorn
uvicorn.run(
app,
host="0.0.0.0",
port=8080,
log_level="debug",
) If you run this server and try to do a HTTP GET request on localhost:8080 you should receive the following error: $ poetry run python src/test.py During handling of the above exception, another exception occurred: Traceback (most recent call last): During handling of the above exception, another exception occurred: Traceback (most recent call last): Python version: 3.10 fastapi = "^0.80.0" |
I tried it as well, and it looks like I overlooked the exception handling interaction with Depends indeed. |
I don't really have time to check it myself right now, but IIRC handlers for any custom exception and a generic Refer to I think it'd also make sense to first reproduce with Starlette instead of FastAPI, even though we want to support both. If you can't make it work using Starlette, it won't work with FastAPI. Again, I assume the reason for missing context there is that this exception handler is run in the outermost middleware and it's not really possible to "make it work differently" (refer to Starlette source), so the previous middleware (starlette-context middleware) already cleaned up after itself. At least that's the case for 500 / Exception. |
I have also tried with a custom exception, with the same error. I'll reproduce it in the afternoon. Anyway i''m using starlette context to save specific header values in the context, because i have to log these informations. My aim is to raise an exception anywhere in my code when something went wrong, and intercept it in fastapi customs exception handler, log the reason of the exception with the current headers informations and fail safe with an appropriate http response. |
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from typing import Dict, Any
from fastapi import Request
from starlette_context import context
from fastapi import FastAPI, Depends, Header
from starlette_context import request_cycle_context
class CustomException(Exception):
def __init__(self, message: str):
self.message = message
super().__init__(self.message)
def __str__(self) -> str:
return f'{self.message}'
async def my_context_dependency(x_plt_user_id: str = Header(None)) -> Any:
data = {"user-id": x_plt_user_id}
with request_cycle_context(data):
# yield allows it to pass along to the rest of the request
yield
app = FastAPI(
dependencies=[Depends(my_context_dependency)],
title="Test App",
)
@app.exception_handler(CustomException)
async def unicorn_exception_handler(request: Request, exc: CustomException) -> JSONResponse:
user_id = context.get("user-id", default=None)
print(user_id)
return JSONResponse(
status_code=400,
content={"message": "Bad Request"},
)
@app.get("/")
async def root() -> Dict[str, str]:
raise CustomException("Test")
return {"message": "Hello World"}
if __name__ == "__main__":
# Use this for debugging purposes only
import uvicorn
uvicorn.run(
app,
host="0.0.0.0",
port=8080,
log_level="debug",
) Same issue |
@mancioshell chances are @hhamana figured it out. Their fix has been released in 0.3.5. Could you please confirm the issue has been resolved? |
@tomwojcik sorry for the delayed reply. Yep i have just tested the issue is solved in 0.3.5. |
Hi,
i'm using Depend FastAPI mechaninsm to access Context on request-response cycle:
I'm also using custom exception handler in FastAPI:
But when i try to access context inside the custom exception handler i receive :
starlette_context.errors.ContextDoesNotExistError: You didn't use the required middleware or you're trying to access
context
object outside of the request-response cycle.Any hints ?
The text was updated successfully, but these errors were encountered: