Aje*_*ngh 13 exception python-3.x fastapi
我是非常新的 python 和 fastapi。我正在尝试在全局级别捕获未处理的异常。所以在main.py文件中的某个地方我写在下面:
@app.exception_handler(Exception)
async def exception_callback(request: Request, exc: Exception):
logger.error(exc.detail)
Run Code Online (Sandbox Code Playgroud)
但上述方法从未执行过。但是如果我编写一个自定义异常并尝试捕获它(如下所示),它运行良好。
class MyException(Exception):
#some code
@app.exception_handler(MyException)
async def exception_callback(request: Request, exc: MyException):
logger.error(exc.detail)
Run Code Online (Sandbox Code Playgroud)
我已经完成了Catch 异常类型的 Exception 和 process body request #575。但是这个错误谈论访问请求正文。看到这个bug,感觉应该可以抓到Exception。FastApi 版本fastapi>=0.52.0。
提前致谢 :)
小智 14
你可以做这样的事情。它应该返回一个 json 对象,其中包含您的自定义错误消息,该对象也可以在调试器模式下工作。
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(Exception)
async def validation_exception_handler(request: Request, exc: Exception):
# Change here to Logger
return JSONResponse(
status_code=500,
content={
"message": (
f"Failed method {request.method} at URL {request.url}."
f" Exception message is {exc!r}."
)
},
)
Run Code Online (Sandbox Code Playgroud)
And*_*ijo 11
如果您想捕获所有未处理的异常(内部服务器错误),有一种非常简单的方法。文档
from fastapi import FastAPI
from starlette.requests import Request
from starlette.responses import Response
app = FastAPI()
async def catch_exceptions_middleware(request: Request, call_next):
try:
return await call_next(request)
except Exception:
# you probably want some kind of logging here
return Response("Internal server error", status_code=500)
app.middleware('http')(catch_exceptions_middleware)
Run Code Online (Sandbox Code Playgroud)
确保将此中间件放在其他所有东西之前。
添加自定义APIRoute也可用于处理全局异常。这种方法的优点是,如果自定义路由引发 http 异常,Starlette 的默认错误处理程序将处理该异常:
from typing import Callable
from fastapi import Request, Response, HTTPException, APIRouter, FastAPI
from fastapi.routing import APIRoute
from .logging import logger
class RouteErrorHandler(APIRoute):
"""Custom APIRoute that handles application errors and exceptions"""
def get_route_handler(self) -> Callable:
original_route_handler = super().get_route_handler()
async def custom_route_handler(request: Request) -> Response:
try:
return await original_route_handler(request)
except Exception as ex:
if isinstance(ex, HTTPException):
raise ex
logger.exception("uncaught error")
# wrap error into pretty 500 exception
raise HTTPException(status_code=500, detail=str(ex))
return custom_route_handler
router = APIRouter(route_class=RouteErrorHandler)
app = FastAPI()
app.include_router(router)
Run Code Online (Sandbox Code Playgroud)
使用 fastapi==0.68.1 为我工作。
有关自定义路由的更多信息:https ://fastapi.tiangolo.com/advanced/custom-request-and-route/
这是 Fastapi 和 Starlette 上的一个已知问题。
我试图通过以下简单示例全局捕获 StarletteHTTPException。
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.responses import JSONResponse
app = FastAPI()
@app.exception_handler(StarletteHTTPException)
async def exception_callback(request: Request, exc: Exception):
print("test")
return JSONResponse({"detail": "test_error"}, status_code=500)
if __name__ == "__main__":
uvicorn.run("test:app", host="0.0.0.0", port=1111, reload=True)
Run Code Online (Sandbox Code Playgroud)
有用。我打开浏览器并调用端点 / 并尝试访问http://127.0.0.1:1111/,它将返回 json {"detail":"test_error"} ,HTTP 代码为 "500 Internal Server Error" 。
但是,当我只将 @app.exception_handler 中的 StarletteHTTPException 更改为 Exception 时,
import uvicorn
from fastapi import FastAPI
from starlette.requests import Request
from starlette.exceptions import HTTPException as StarletteHTTPException
from starlette.responses import JSONResponse
app = FastAPI()
@app.exception_handler(Exception)
async def exception_callback(request: Request, exc: Exception):
print("test")
return JSONResponse({"detail": "test_error"}, status_code=500)
if __name__ == "__main__":
uvicorn.run("test:app", host="0.0.0.0", port=1111, reload=True)
Run Code Online (Sandbox Code Playgroud)
当我访问http://127.0.0.1:1111/时,异常回调方法无法捕获 StarletteHTTPException 。报404错误。
异常行为应该是: StarletteHTTPException 错误可以通过 Exception 修饰的方法 exception_handler 捕获,因为 StarletteHTTPException 是 Exception 的子类。
然而,这是 Fastapi 和 Starlette 中报告的一个已知问题
所以我们目前还无法实现这个目标。
| 归档时间: |
|
| 查看次数: |
9007 次 |
| 最近记录: |