fastapi
fastapi copied to clipboard
HTTP_500_INTERNAL_SERVER_ERROR cause a CORS error on frontend
First Check
- [X] I added a very descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the FastAPI documentation, with the integrated search.
- [X] I already searched in Google "How to X in FastAPI" and didn't find any information.
- [X] I already read and followed all the tutorial in the docs and didn't find an answer.
- [X] I already checked if it is not related to FastAPI but to Pydantic.
- [X] I already checked if it is not related to FastAPI but to Swagger UI.
- [x] I already checked if it is not related to FastAPI but to ReDoc.
Commit to Help
- [X] I commit to help with one of those options 👆
Example Code
all code is in Description
Description
It is hard to show all main code of my project, I would show part of my code below.
- I already processed CORS in fastapi, I am sure it work when axios request is successful.
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
- My way to handle global exception is adding a middlware, and when my code raise a AttributeError by itself, frontend would get a CORS error and axios shows that error.response is undefined
@app.middleware('http')
async def catch_exceptions_middleware(request: Request, call_next):
try:
return await call_next(request)
except Exception as e:
# from fastapi.responses import JSONResponse
# from fastapi import status
logger.debug(f"middware catch the error")
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content="Unknow Error"
)
- But when I use
exception_handler
to catch the certain exception, there is no CORS error, and axios shows error.response successfully. Sadly, it cound not work well to catch all the other exception when i use@app.exception_handler(Exception)
@app.exception_handler(AttributeError)
async def all_exception_handler(request: Request, exc: Exception):
# from fastapi.responses import JSONResponse
# from fastapi import status
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content="Unknow Error"
)
- By all above, my question is , how cound I catch a global exception to ensure that there is no CORS error on frontend?
Operating System
Windows
Operating System Details
win10 uvicorn 0.15.0 starlette 0.16.0
FastAPI Version
0.70.0
Python Version
Python 3.7.10
Additional Context
No response
It's starlette
issue - https://github.com/encode/starlette/issues/1116
It's
starlette
issue - encode/starlette#1116
yep, i had read it before i issued, i could not found a solution yet. And I still could not figure out that it was a bug or somethig, like feature?
I believe it's a bug.
As a temporary workaround, you can add ServerErrorMiddleware
middleware with global exc handler before all middlewares:
from starlette.middleware.errors import ServerErrorMiddleware
from starlette.requests import Request
from starlette.types import ASGIApp
from fastapi import FastAPI, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
async def global_execution_handler(request: Request, exc: Exception) -> ASGIApp:
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content="Unknown Error",
)
app = FastAPI()
app.add_middleware(
ServerErrorMiddleware,
handler=global_execution_handler,
)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
I believe it's a bug.
As a temporary workaround, you can add
ServerErrorMiddleware
middleware with global exc handler before all middlewares:from starlette.middleware.errors import ServerErrorMiddleware from starlette.requests import Request from starlette.types import ASGIApp from fastapi import FastAPI, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse async def global_execution_handler(request: Request, exc: Exception) -> ASGIApp: return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content="Unknown Error", ) app = FastAPI() app.add_middleware( ServerErrorMiddleware, handler=global_execution_handler, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
thanks a lot, it works! Waiting for offical fixing.
Had the same problem, thanks. Could someone please ping me once there will be an official fix?
I believe it's a bug.
As a temporary workaround, you can add
ServerErrorMiddleware
middleware with global exc handler before all middlewares:from starlette.middleware.errors import ServerErrorMiddleware from starlette.requests import Request from starlette.types import ASGIApp from fastapi import FastAPI, status from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import JSONResponse async def global_execution_handler(request: Request, exc: Exception) -> ASGIApp: return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, content="Unknown Error", ) app = FastAPI() app.add_middleware( ServerErrorMiddleware, handler=global_execution_handler, ) app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )
I think this workaround
needs to be put into the fastapi official doc, as the starlette team ( here and here ) considers this is a feature, not a bug.