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}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/87178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

408第一季 - 数据结构 - 排序

排序的概念 外部排序很难,后面都是内部排序 插入排序 直接插入排序 理解 这个排序第一轮是从第二个元素开始的 然后是从后往前一个一个比的 然后我们看i5的情况,会出现比较次数和移动次数的概念,这里97动了 然后i8时,49最好…

高效账号信息管理工具,可安全随机生成密码

软件介绍 今天给大家推荐一款安全可靠的密码管理工具,帮助用户轻松管理各类账号密码。 安全便捷的密码解决方案 这是一款采用先进加密技术开发的密码管理器,不仅可以生成高强度随机密码,还提供安全的账号密码备份存储功能。 基础安全设置 …

如何在markdown文件中(博客)添加emoji表情,让你的博客看起来更加优雅

在Markdown中使用Emoji的完整指南 按分类快速参考的完整Emoji列表一、状态指示类:bulb:二、提示信息类:bulb:三、内容类型类:bulb:四、操作指令类:bulb:五、进度状态类:bulb:六、技术相关类:bulb:七、人员角色类:bulb:八、版本控制类:bulb: 你学会了吗 按分类快速参考的完整Emo…

MAZANOKE:一款隐私优先的浏览器图像优化工具及Docker部署指南

在日常工作中,大家是否经常遇到这样的需求:需要压缩图片体积、调整图片尺寸或转换图片格式,但又受限于数据安全要求无法将图片上传至公网?在我们之前开发的工单配置系统中,这类需求尤为常见。最近在GitHub上发现了一款…

【Vue PDF】Vue PDF 组件初始不加载 pdfUrl 问题分析与修复

Vue PDF 组件初始不加载 pdfUrl 问题分析与修复 问题现象 在开发 PDF 预览组件时,遇到这样一个问题: 初始状态下,PDF 组件不会请求 pdfUrl(即不会加载 PDF 文件)。只有点击"全屏"按钮后,才会请…

《注解的江湖:一场元数据的“宫斗剧”》

一、你真的懂注解吗 你是否使用过Autowired却不知道是如何生效的? 这几个注解你一定很熟悉: OverrideDeprecatedTransactional 那么你有进一步思考过怎么生效的吗?注解到底是什么?注解,到底是信息?还是指…

智能土木通 - 土木工程专业知识问答系统02-RAG检索模块搭建

一、项目目录 civil_qa_system/ ├── docs/ # 项目文档 ├── config/ # 配置文件 ├── core/ # 核心功能代码 ├── knowledge_base/ # 知识库相关 ├── web/ # Web应用部分 ├…

进程和线程区别、管道和套接字、共享变量、TCP三次握手,是否可以少一次握手、子进程和主进程区别和API——Nodejs

首先讲了进程和线程区别 然后讲解 管道和套接字,它是进程间通信的方式 接着讲解共享变量 ,它是线程间通信 最后讲解TCP三次握手,因为套接字使用了TCP协议 一、线程和进程的区别 线程(Thread)和进程(Pr…

docker(学习笔记第一课) 使用nginx +https + wordpress

文章目录 docker(学习笔记第一课) 使用nginx https wordpress学习内容:1. 整体架构1.1 在aws ec2的整体架构1.2 不懂都可以问AI 2. 构建详细2.1 构建ec22.2 安装docker2.3 创建一个docker的内部network2.4 创建wordpress使用的mysql数据库2.5 创建两个wordpress的d…

Leetcode 刷题记录 15 —— 二分查找

本系列为笔者的 Leetcode 刷题记录,顺序为 Hot 100 题官方顺序,根据标签命名,记录笔者总结的做题思路,附部分代码解释和疑问解答,01~07为C语言,08及以后为Java语言。 01 搜索插入位置 class Solution {pub…

C++核心编程(动态类型转换,STL,Lanmda)

一. 类型转换 二. STL 1. 容器 1.1 Vector(常用) 1.1.1 概述 特性: 动态数组: 想象成一个会自动变长变短的数组。起始在内存中是连续存储的。 随机访问: 通过[]运算符或at()方法,可以瞬间(…

【图像处理入门】8. 数学基础与优化:线性代数、概率与算法调优实战

摘要 图像处理的核心离不开数学工具的支撑。本文将深入解析线性代数、概率论在图像领域的应用,包括矩阵变换与图像几何操作的关系、噪声模型的数学描述,以及遗传算法、粒子群优化等智能算法在参数调优中的实践。通过理论结合代码案例,帮助读者掌握从数学原理到工程优化的完…

操作系统八股文

一.进程和线程的区别 1.本质区别和所属关系是什么? 进程是资源调度以及分配的基本单位。 线程是CPU调度的基本单位。 一个线程属于一个进程,一个进程可以拥有多个线程。 2.地址空间和内存 进程拥有独立的虚拟地址空间。 线程没有独立的地址空间&#xf…

【uniapp】小程序中input输入框的placeholder-class不生效

解决方法 1.去掉scoped <style></style> 2.额外写一组style </style lang"scss" scoped> </style> <style> ::v-deep .textarea-placeholder { font-size: 24rpx; font-weight: 400; …

大模型训练与推理显卡全指南:从硬件选型到性能优化

在人工智能技术飞速发展的今天&#xff0c;大型语言模型(LLM)已成为推动行业进步的核心动力。然而&#xff0c;训练和部署这些“数字巨人”需要强大的计算基础设施作为支撑&#xff0c;其中GPU的选择直接决定了模型开发的效率与成本。本文将全面剖析当前主流GPU型号在大模型训练…

Linux Docker的环境配置与简单使用

参考资料 Windows Docker Desktop设置中文【Docker 】Docker Desktop for Windows&#xff08;WSL 2&#xff09;安装WSL 2 上的 Docker 远程容器入门 目录 一. 环境配置1.1 安装WSL1.2 安装配置 Docker Desktop1.3 VS Code 插件安装1.4 下载项目&#xff0c;配置Dockerfile 二…

函数指针与指针函数:本质区别与高级应用

目录 一、概念本质解析 1. 函数指针&#xff08;Function Pointer&#xff09; 2. 指针函数&#xff08;Pointer Function&#xff09; 二、函数指针深度剖析 1. 基础用法示例 2. 高级应用&#xff1a;回调函数 3. 函数指针数组 三、指针函数深入探讨 1. 基础实现模式 …

【python】基于pycharm的海康相机SDK二次开发

海康威视二次开发相机管理 这段代码基于python开发的&#xff0c;用了opencv的一些库函数。实现了一个完整的海康机器人相机管理工具&#xff0c;支持多相机连接、参数配置、图像采集和实时显示功能。目前USB相机测试无误&#xff0c;除了丢一些包。 1. 主要类结构 HKCameraM…

HTTP 协议各个主要版本的功能特点、核心原理、使用场景总结

我们来系统总结一下 HTTP 协议各个主要版本的功能特点、核心原理&#xff08;用图示辅助说明&#xff09;以及典型使用场景。 核心演进目标&#xff1a; 提升性能、安全性、效率和灵活性。 1. HTTP/0.9 (1991) - 远古雏形 功能特点: 极其简单&#xff1a; 只支持 GET 方法。无…

Linux编程:3、进程通信-信号

一、进程通信概述 &#xff08;一&#xff09;进程通信的目的 在企业开发中&#xff0c;一个项目常常需要多个进程共同协作&#xff0c;而这些进程之间需要进行通信&#xff08;交换信息&#xff09;以便协作。本章内容主要围绕信号讲解&#xff0c;其它进程通信的常用方式请…