【FastAPI 學習 六】異常處理
阿新 • • 發佈:2020-12-26
異常處理
統一捕獲處理異常,使得程式碼更加完善,健壯。
框架內建了一些異常,當然也可以自己定義異常然後捕獲處理。
完全可以參考官網(超喜歡這種風格的文件):
https://fastapi.tiangolo.com/tutorial/handling-errors/
異常捕獲
在FastAPI中,最常見的就是請求引數驗證異常處理,因為FastAPI全面使用了pydantic
來做資料型別校驗,所以最常見的異常就是ValidationError
, 然後FastAPI繼承了這個錯誤,專門捕獲請求引數異常的RequestValidationError
捕獲異常的語法
from fastapi.exceptions import RequestValidationError @app.exception_handler(RequestValidationError) async def request_validation_exception_handler(request: Request, exc: RequestValidationError): """ 請求引數驗證異常 :param request: 請求頭資訊 :param exc: 異常物件 :return: """ # 日誌記錄異常詳細上下文 logger.error(f"全域性異\n{request.method}URL{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}") return response_code.resp_422(message=exc.errors())
自定義異常
我是這樣做的,在utils/custom_exc.py
檔案下定義好各種異常
class UserTokenError(Exception):
def __init__(self, err_desc: str = "使用者認證異常"):
self.err_desc = err_desc
class UserNotFound(Exception):
def __init__(self, err_desc: str = "沒有此使用者"):
self.err_desc = err_desc
丟擲自定異常
先倒入異常,然後raise丟擲
from utils import custom_exc
# xxxx
raise custom_exc.UserTokenError(err_desc="access token fail")
捕獲自定異常
這個和內建異常捕獲語法是一樣的
@app.exception_handler(UserTokenError) async def user_token_exception_handler(request: Request, exc: UserTokenError): """ 使用者token異常 :param request: :param exc: :return: """ logger.error(f"使用者認證異常\nURL:{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}") return response_code.resp_5000(message=exc.err_desc)
註冊異常
一般專案中會捕獲各種異常, 最好就是把異常函式集中起來,我是模仿Flask
框架來寫的,所以FastAPI
捕獲異常語法也類似
def create_app():
"""
生成FatAPI物件
:return:
"""
app = FastAPI()
# 其餘的一些全域性配置可以寫在這裡 多了可以考慮拆分到其他資料夾
# 跨域設定
# register_cors(app)
# 註冊路由
# register_router(app)
# 註冊捕獲全域性異常
register_exception(app)
# 請求攔截
# register_middleware(app)
return app
def register_static_file(app: FastAPI) -> None:
# 自定義異常 捕獲
@app.exception_handler(UserNotFound)
async def user_not_found_exception_handler(request: Request, exc: UserNotFound):
"""
使用者認證未找到
:param request:
:param exc:
:return:
"""
logger.error(f"token未知使用者\nURL:{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}")
return response_code.resp_5001(message=exc.err_desc)
# 捕獲全部異常
@app.exception_handler(Exception)
async def all_exception_handler(request: Request, exc: Exception):
"""
全域性所有異常
:param request:
:param exc:
:return:
"""
logger.error(f"全域性異常\n{request.method}URL:{request.url}\nHeaders:{request.headers}\n{traceback.format_exc()}")
return response_code.resp_500(message="伺服器內部錯誤")
異常詳情
上一章部落格有提過,使用traceback
列印詳細異常
import traceback
logger.error(traceback.format_exc())
總結
以上就是最基本的捕獲異常的寫法,捕獲好異常,可以幫助更快更友好的排錯,是介面返回格式更加規範。
注意
捕獲異常函式別手誤寫錯了,多加個s
, 寫成@app.exception_handlers,就會報如下異常
@app.exception_handlers(UserTokenError)
TypeError: 'dict' object is not callable
對應程式碼Github地址
見個人網站 https://www.charmcode.cn/article/2020-07-19_fastapi_exception