<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          全面擁抱FastApi —優(yōu)雅的返回異常錯誤

          共 4157字,需瀏覽 9分鐘

           ·

          2020-12-24 02:21

          點擊“Python編程與實戰(zhàn)”,選擇“置頂公眾號”

          第一時間獲取 Python 技術(shù)干貨!

          在開發(fā)接口或者服務(wù)的時候,經(jīng)常會遇到需要給客戶端返回異常錯誤 例如:

          • 用戶操作權(quán)限不夠
          • 參數(shù)錯誤
          • 請求的資源不存在..

          眾所周知,因客戶端或調(diào)用方的原因?qū)е鲁鲥e的,返回的狀態(tài)碼是以 4 開頭的 (400~499)

          比如常見的 404 Not Found, 資源不存在...

          為了直觀友好的給客戶端返回錯誤, 在 FastApi 中一般使用 HTTPException

          from?fastapi?import?FastAPI,?HTTPException

          app?=?FastAPI()

          items?=?{"foo":?"The?Foo?Wrestlers"}


          @app.get("/items/{item_id}")
          async?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]}

          當遇到用戶請求異常的時候,可以選擇用 raise 將異常拋出去

          拋出異常,便立即會結(jié)束本次請求,并將HTTP錯誤從HTTPException發(fā)送到客戶端或瀏覽器

          比如:在瀏覽器中輸入 http://127.0.0.1:8000/items/jerry

          由于 jerry 并不在 items 中,瀏覽器便會收到 404 以及一個 json 格式的 response

          注意:這個 json 由 FastAPI 自動處理并轉(zhuǎn)換的。

          自定義異常類

          和 starlette 源碼中處理異常一樣,你也可以自定義一個異常處理類 定義的異常處理類,使用 @app.exception_handler() 支持在 FastAPI 中全局使用該異常類

          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=418,
          ????????content={"message":?f"Oops!?{exc.name}?did?something.?There?goes?a?rainbow..."},
          ????)

          在路由函數(shù)中,使用該類

          @app.get("/unicorns/{name}")
          async?def?read_unicorn(name:?str):
          ????if?name?==?"yolo":
          ????????raise?UnicornException(name=name)
          ????return?{"unicorn_name":?name}

          運行服務(wù)后,請求服務(wù)路徑 /unicorns/yolo

          在客戶端就能收到一個提示友好,并事先定義好狀態(tài)碼 418 的提示錯誤

          重寫默認異常類

          FastAPI 有許多的默認異常處理類

          這些處理程序負責在引發(fā) HTTPException 和請求包含無效數(shù)據(jù)時返回默認 JSON 響應(yīng)

          比如下面的路由是只支持 item_idint 類型的路徑函數(shù)

          @app.get("/items/{item_id}")
          async?def?read_item(item_id:?int):
          ????if?item_id?==?3:
          ????????raise?HTTPException(status_code=418,?detail="Nope!?I?don't?like?3.")
          ????return?{"item_id":?item_id}

          當從客戶端傳過來的 item_id 為非 int 類型的時候,便返回默認的 JSON 響應(yīng)

          你可以重寫這些默認的異常處理類,變成自定義的。比如

          重寫請求驗證異常類

          當一個請求包含非法的請求數(shù)據(jù)時,會觸發(fā) FastAPI 中的 RequestValidationError

          為了重寫該異常處理類,需要導(dǎo)入 RequestValidationError, 并使用 @app.exception_handler(RequestValidationError) 對異常處理函數(shù)進行裝飾

          from?fastapi.exceptions?import?RequestValidationError

          @app.exception_handler(RequestValidationError)
          async?def?validation_exception_handler(request,?exc):
          ????return?PlainTextResponse(str(exc),?status_code=400)

          將這部分代碼,和上面的代碼合并后運行。再次請求會看到不一樣的提示~~~

          重寫 HTTPException

          同樣,你也可以重寫 HTTPException 處理程序

          比如你想返回文本的錯誤提示,而不是默認的 JSON 格式錯誤提示

          和上面一樣,使用 @app.exception_handler(HTTPException) 裝飾異常處理函數(shù)即可

          from?fastapi.responses?import?PlainTextResponse
          from?starlette.exceptions?import?HTTPException?as?StarletteHTTPException

          app?=?FastAPI()

          @app.exception_handler(StarletteHTTPException)
          async?def?http_exception_handler(request,?exc):
          ????return?PlainTextResponse(str(exc.detail),?status_code=exc.status_code)

          @app.get("/items/{item_id}")
          async?def?read_item(item_id:?int):
          ????if?item_id?==?3:
          ????????raise?HTTPException(status_code=418,?detail="Nope!?I?don't?like?3.")
          ????return?{"item_id":?item_id}

          返回異常請求body

          當接收到非法請求的時候,RequestValidationError 中包含異常請求體的,只是沒有給我們返回

          但是在開發(fā)應(yīng)用程序或者與前端聯(lián)調(diào)的時候,可以將請求體加到返回的 response

          這樣在出現(xiàn)問題的時候,可以通過日志或響應(yīng),快速定位到問題!

          from?fastapi?import?FastAPI,?Request,?status
          from?fastapi.encoders?import?jsonable_encoder
          from?fastapi.exceptions?import?RequestValidationError
          from?fastapi.responses?import?JSONResponse
          from?pydantic?import?BaseModel

          app?=?FastAPI()

          @app.exception_handler(RequestValidationError)
          async?def?validation_exception_handler(request:?Request,?exc:?RequestValidationError):
          ????return?JSONResponse(
          ????????status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
          ????????content=jsonable_encoder({"detail":?exc.errors(),?"body":?exc.body}),
          ????)

          class?Item(BaseModel):
          ????title:?str
          ????size:?int

          @app.post("/items/")
          async?def?create_item(item:?Item):
          ????return?item

          我們來觸發(fā)下異常,比如請求體:

          {
          ??"title":?"towel",
          ??"size":?"XL"
          }

          對于異常請求,收到的響應(yīng)中就會包含該次異常請求的請求 body

          {
          ??"detail":?[
          ????{
          ??????"loc":?[
          ????????"body",
          ????????"size"
          ??????],
          ??????"msg":?"value?is?not?a?valid?integer",
          ??????"type":?"type_error.integer"
          ????}
          ??],
          ??"body":?{
          ????"title":?"towel",
          ????"size":?"XL"
          ??}
          }

          在聯(lián)調(diào)或開發(fā)的時候,可以節(jié)省一些不必要的時間,提高效率!

          推薦閱讀

          全面擁抱FastApi —三大參數(shù)及驗證

          全面擁抱 FastApi — 多應(yīng)用程序項目結(jié)構(gòu)規(guī)劃


          瀏覽 404
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一级av | 黑人精品欧美一区二区蜜桃 | 久久手机观看 | 无套内射美女 | 精品无码av一区二区三区不卡 |