系列文章:
FastAPI 學習之路(一)fastapi--高性能web開發框架
FastAPI 學習之路(十二)接口幾個額外信息和額外數據類型
FastAPI 學習之路(十三)Cookie 參數,Header參數
某些情況下,需要向客戶端返回錯誤提示。
這里所謂的客戶端包括前端瀏覽器、其他應用程序、物聯網設備等。
需要向客戶端返回錯誤提示的場景主要如下:
-
客戶端沒有執行操作的權限
-
客戶端沒有訪問資源的權限
-
客戶端要訪問的項目不存在
-
等等 ...
遇到這些情況時,通常要返回 4XX(400 至 499)HTTP 狀態碼。
4XX 狀態碼與表示請求成功的 2XX(200 至 299) HTTP 狀態碼類似。
只不過,4XX 狀態碼表示客戶端發生的錯誤。
如何處理呢,我們通過一段代碼來演示
from fastapi import FastAPI, HTTPException app = FastAPI() items = {"test": "雷子說測試開發"} @app.get("/items/{item_id}") def read_item(item_id: str): if item_id not in items: raise HTTPException(status_code=404, detail="Item not found") return {"item": items[item_id]}
我們看下接口的返回

這是正常的接口返回,我們來看下我們錯誤的異常返回

我們可以看到這個時候可以正常返回,但是我們的狀態碼已經被我們改成404了。
HTTPException 是額外包含了和 API 有關數據的常規 Python 異常。
因為是 Python 異常,所以不能 return,只能 raise。
如在調用路徑操作函數里的工具函數時,觸發了 HTTPException,FastAPI 就不再繼續執行路徑操作函數中的后續代碼,而是立即終止請求,並把 HTTPException 的 HTTP 錯誤發送至客戶端。
響應結果
請求為 http://example.com/items/test(item_id 為 test)時,客戶端會接收到 HTTP 狀態碼 - 200 及如下 JSON 響應結果:
{ "item": "雷子說測試開發"}
但如果客戶端請求 http://example.com/items/test1(item_id 為test1 不存在時),則會接收到 HTTP 狀態碼 - 404(「未找到」錯誤)及如下 JSON 響應結果:
{ "detail": "Item not found" }
觸發 HTTPException 時,可以用參數 detail 傳遞任何能轉換為 JSON 的值,不僅限於 str。
還支持傳遞 dict、list 等數據結構。
FastAPI 能自動處理這些數據,並將之轉換為 JSON。
添加自定義響應頭
有些場景下要為 HTTP 錯誤添加自定義響應頭。例如,出於某些方面的安全需要。
我們看下如何自定義響應頭
from fastapi import FastAPI, HTTPException app = FastAPI() items = {"test": "雷子說測試開發"} @app.get("/items/{item_id}") def read_item(item_id: str): if item_id not in items: raise HTTPException(status_code=404, detail="Item not found", headers={"X-Error": "NADOR"}, ) return {"item": items[item_id]}
結果如下:

我們還可以去自定義我們的異常處理器。我們看下如何來實現的。
from fastapi import FastAPI, Request from fastapi.responses import JSONResponse class UnicornException(Exception): def __init__(self, name: str): self.name = name app = FastAPI() @app.exception_handler(UnicornException) async def unicorn_exception_handler(request: Request, exc: UnicornException): return JSONResponse( status_code=408, content={"message": f"Oops! {exc.name} "}, ) @app.get("/one/{name}") async def one(name: str): if name == "leizi": raise UnicornException(name=name) return {"name": name}
我們可以看到,我們的實現其實很簡單。用 @app.exception_handler() 即可添加自定義異常控制器。
我們請求下,當我們的名稱等於雷子的時候,就是返回我們自定義的異常。
正常的請求

那么就可以看到,我們去實現的自定義的異常是成功的。
FastAPI 自帶了一些默認異常處理器。
觸發 HTTPException 或請求無效數據時,這些處理器返回默認的 JSON 響應結果。
不過,也可以使用自定義處理器覆蓋默認異常處理器。
文章首發在公眾號,歡迎關注。

