当前位置: 首页 > news >正文

FastAPI:(6)错误处理

FastAPI:(6)错误处理

由于CSDN无法展示「渐构」的「#d,#e,#t,#c,#v,#a」标签,推荐访问我个人网站进行阅读:Hkini
「渐构展示」如下:在这里插入图片描述
在这里插入图片描述

#c 概述 文章概念关系

graph TDA[错误处理] --> B[HTTPException]A --> C[自定义异常类]A --> D[异常处理器]D --> E[注册处理器]E --> F[@app.exception_handler]B --> G[状态码]B --> H[detail]B --> I[headers]C --> J[UnicornException]D --> K[RequestValidationError]K --> L[请求体]K --> M[覆盖默认处理器]D --> N[复用默认处理器]N --> O[fastapi.exception_handlers]

#d 错误处理

错误处理是指在应用运行过程中对可能发生的异常或错误进行捕获、统一响应和返回格式化错误信息的机制。FastAPI 支持对内建异常(如 HTTPException)的处理,以及自定义异常类型的注册和响应方式。良好的错误处理机制可以提升 API 的鲁棒性、用户体验和调试效率。

重要特征

  • 特征1基于 HTTPException 或自定义异常类
    FastAPI 默认支持 fastapi.HTTPException,也允许定义自己的异常类和异常处理器。
  • 特征2响应内容结构化,可自定义状态码、消息和返回体
    错误响应可包括 status_codedetailheaders 等字段。
  • 特征3通过 @app.exception_handler 注册处理器
    可针对特定异常类型定义处理逻辑,统一捕获并生成响应。
  • 特征4与路径操作函数逻辑解耦
    使主业务代码更简洁清晰,错误处理集中统一。

#e 订单查询异常处理(正例)

现象:
在一个电商平台中,用户根据订单 ID 查询订单详情。若订单不存在,则抛出 HTTPException(404),返回“订单未找到”的错误响应。

特征对比

特征是否满足
使用 HTTPException 或自定义异常✅ 使用内建 HTTPException
响应结构规范(状态码、消息)✅ 设置 404 + detail
捕获逻辑清晰明确✅ 异常直接由业务逻辑触发
与主业务逻辑解耦✅ 查询失败即抛异常,无需后续处理判断
from fastapi import FastAPI, HTTPExceptionapp = FastAPI()fake_orders = {"123": "订单123内容", "456": "订单456内容"}@app.get("/order/{order_id}")
async def get_order(order_id: str):if order_id not in fake_orders:raise HTTPException(status_code=404, detail="订单未找到")return {"order_id": order_id, "content": fake_orders[order_id]}

HTTPException 是额外包含了和 API 有关数据的常规 Python 异常。因为是 Python 异常,所以不能 return,只能 raise

如在调用「路径操作函数」里的工具函数时,触发了 HTTPException,FastAPI 就不再继续执行_路径操作函数_中的后续代码,而是立即终止请求,并把 HTTPException 的 HTTP 错误发送至客户端。

触发 HTTPException 时,可以用参数 detail 传递任何能转换为 JSON 的值,不仅限于 str。还支持传递 dictlist 等数据结构。FastAPI 能自动处理这些数据,并将之转换为 JSON。

#e return 返回错误信息(反例)

现象:
当用户输入非法请求时,系统返回如下内容:

return {"error": "invalid input"}

并未使用 HTTP 状态码或异常处理机制。

特征对比

特征是否满足
使用 HTTPException 或自定义异常❌ 直接 return,未抛异常
响应结构标准❌ 未设置状态码,结构不规范
捕获逻辑统一❌ 所有错误需开发者手动处理
与主业务解耦❌ 错误处理混杂在主逻辑中,易出错

#e 自定义响应头

有些场景下要为 HTTP 错误添加自定义响应头。例如,出于某些方面的安全需要。一般情况下可能不会需要在代码中直接使用响应头。但对于某些高级应用场景,还是需要添加自定义响应头:

from fastapi import FastAPI, HTTPExceptionapp = FastAPI()items = {"foo": "The Foo Wrestlers"}@app.get("/items-header/{item_id}")
async def read_item_header(item_id: str):if item_id not in items:raise HTTPException(status_code=404,detail="Item not found",headers={"X-Error": "There goes my error"}, # 添加响应头)return {"item": items[item_id]}

#e 自定义异常处理器

添加自定义处理器,要使用 Starlette 的异常工具。假设要触发的自定义异常叫作 UnicornException。且需要 FastAPI 实现全局处理该异常。此时,可以用 @app.exception_handler() 添加自定义异常控制器:

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponseclass UnicornException(Exception):def __init__(self, name: str):self.name = nameapp = 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..."},)@app.get("/unicorns/{name}")
async def read_unicorn(name: str):if name == "yolo":raise UnicornException(name=name)return {"unicorn_name": name}

请求 /unicorns/yolo 时,路径操作会触发 UnicornException
但该异常将会被 unicorn_exception_handler 处理。
接收到的错误信息清晰明了,HTTP 状态码为 418,JSON 内容如下:

{"message": "Oops! yolo did something. There goes a rainbow..."}

#e 覆盖请求验证异常

「请求中包含无效数据」时,FastAPI 内部会触发 RequestValidationError。该异常也内置了默认异常处理器。

覆盖默认异常处理器时需要导入 RequestValidationError,并用 @app.excption_handler(RequestValidationError) 装饰异常处理器。这样,异常处理器就可以接收 Request 与异常。

from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPExceptionapp = FastAPI()@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):return PlainTextResponse(str(exc.detail), status_code=exc.status_code)@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):return PlainTextResponse(str(exc), status_code=400)@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}

#e 覆盖 HTTPException 处理器

只为错误返回纯文本响应,而不是返回 JSON 格式的内容。

from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from fastapi.responses import PlainTextResponse
from starlette.exceptions import HTTPException as StarletteHTTPExceptionapp = FastAPI()@app.exception_handler(StarletteHTTPException)
async def http_exception_handler(request, exc):return PlainTextResponse(str(exc.detail), status_code=exc.status_code)@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):return PlainTextResponse(str(exc), status_code=400)@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}

#e RequestValidationError 的请求体

RequestValidationError 包含其接收到的无效数据请求的 body
开发时,可以用这个请求体生成日志、调试错误,并返回给用户。

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 BaseModelapp = 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: strsize: int@app.post("/items/")
async def create_item(item: Item):return item

发送无效item

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

收到422,Error: Unprocessable Entity的body响应体。

```json
{"detail": [{"type": "int_parsing","loc": ["body","size"],"msg": "Input should be a valid integer, unable to parse string as an integer","input": "XL"}],"body": {"title": "towel","size": "XL"}
}

#e 复用FastAPI异常处理器

FastAPI 支持先对异常进行某些处理,然后再使用 FastAPI 中处理该异常的默认异常处理器。从 fastapi.exception_handlers 中导入要复用的默认异常处理器,可以在处理异常之后再复用默认的异常处理器。

from fastapi import FastAPI, HTTPException
from fastapi.exception_handlers import (http_exception_handler,request_validation_exception_handler,
)
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPExceptionapp = FastAPI()@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):print(f"OMG! An HTTP error!: {repr(exc)}")return await http_exception_handler(request, exc)@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):print(f"OMG! The client sent invalid data!: {exc}")return await request_validation_exception_handler(request, exc)@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}

相关文章:

  • 自然语言处理相关基本概念
  • 【Docker基础】Docker核心概念:命名空间(Namespace)之IPC详解
  • 【一手实测】字节豆包 1.6 + Trae + 火山 MCP + FaaS:AI云原生 Agent 开发部署全流程体验!
  • Java 9 新特性全面解析:革命性模块化系统与十大核心功能详解
  • Gödel Rescheduler:适用于云原生系统的全局最优重调度框架
  • Windows系统安装Java web开发环境
  • ELK在Java的使用
  • 华为OD-2024年E卷-找终点[100分] -- python
  • Anaconda 安装教程(Windows/macOS/Linux)
  • 数字孪生技术助力:UI前端设计的精准度与效率双提升
  • STM32L431中,低功耗模式下的仿真调试功能受到限制
  • 解锁AI密码:全面赋能海外社媒矩阵运营
  • 【2023 - 2025 年】6大PLM系统主要干活,提升项目管理效率
  • SEO 与性能优化说明文档
  • Leap Micro不可变Linux
  • USB接口DP(D-)和DM(D+)英文全称
  • EMAGE:通过具表现力的掩码音频动作建模,实现统一的整体共语姿态生成
  • 设置Git和Github
  • 【Python打卡Day44】预训练模型 @浙大疏锦行
  • ACM设计平台-核心模块解析-赵家康
  • 个人网站数据库怎么做/西安危机公关公司
  • asp静态网站源码/百度搜索引擎优化详解
  • 域名到期对网站的影响/国外seo工具
  • 做网站外包哪家好/传统营销和网络营销的区别
  • 微应用和微网站的区别/希爱力双效片副作用
  • 长春移动网站建设/中国今天新闻最新消息