FastAPI从入门到实战(12)——错误处理

2023-11-04

错误提示是非常重要的,比如权限控制、资源控制等场景,需要服务器返回给用户错误提示,包括状态码和提示等内容,所以本文就主要记录FastAPI里的错误处理相关的内容

抛出一个HTTPException

@app08.get("/stu08/{id}")
def stu08_get_error(
        id: str = Path(...)
):
    if id != "MinChess":
        return HTTPException(status_code=404, detail="not found")
    return {
        "name": "MinChess",
        "age": 22,
        "Blog": "https://blog.jiumoz.com"
    }

fastapi中导入HTTPException,并在路径操作函数中进行判断输出即可;

上面的代码就是当输入的id不为MinChess的时候抛出错误,错误代码为404,详细信息为not found

image-20221203164124803

添加自定义响应头

@app08.get("/stu08/header/{id}")
def stu08_get_error_header(
        id: str
):
    if id != "MinChess":
        raise HTTPException(
            status_code=404,
            detail="Not Found",
            headers={"X-Error": "There gose my error."}
        )
    return {
        "name": "MinChess",
        "age": 22,
        "Blog": "https://blog.jiumoz.com"
    }

有些场景的前端可能需要在HTTP的错误中添加一些自定义的响应头,添加方法如上,直接设置HTTPExceptionheaders即可;

image-20221203164434584

自定义异常处理器

定义一个Exception类型错误类UnicornException,在实际应用中就对应登录失败错误、验证码错误等;

class UnicornException(Exception):
    def __init__(self, name: str):
        self.name = name

在主应用中为UnicornException错误定义处理函数,如果没在同一个文件内,需要导入对应的类,参考文末的源码;

@app.exception_handler(exception.UnicornException) # 用@app.exception_handler() 为UnicornException添加自定义异常控制器
async def unicorn_exception_handler(request: Request, exc: exception.UnicornException):
    """
    :param request: 请求头
    :param exc: 异常对象
    :return:
    """
    print(f"全局自定义异常:method:{request.method} URL:{request.url}Headers:{request.headers}")
    return JSONResponse(
        status_code=418,
        content={
            "message": f"你输入的: {exc.name} 是错的!!!"
        }
    )

在应用中进行声明即可,要导入相关的类;

@app08.get("/stu08/custom/{name}")
async def stu08_custom(
        name: str = Path(default="MinChess")
):
    if name == "MinChess":
        raise UnicornException(name=name)
    return {"name": "MinChess"}

上面的函数就是当用户输入的name为MinChess的时候,抛出一个UnicornException错误;这里的错误处理函数要实现全局处理的话,就一定要挂载道主应用上;

根据上面的处理函数,我们操作输入MinChess的时候,不仅会返回给前端既定的数据,也会在控制台进行相关信息的输出,如下:

image-20221203164558523

image-20221203164641276

重写默认异常处理器

重写默认的异常处理器就是将fastapi内置的默认异常进行人为干预,方法很简单,同上面的方法,进行重写即可;

@app.exception_handler(RequestValidationError)  # 重写请求验证异常处理器
async def request_validation_exception_handler(request: Request, exc: RequestValidationError):
    """
    请求参数验证异常
    :param request: 请求头信息
    :param exc: 异常对象
    :return:
    """
    # 日志记录异常详细上下文
    print(f"全局异常:{request.method}URL{request.url}Headers:{request.headers}{traceback.format_exc()}")
    return PlainTextResponse(str(exc), status_code=400)


@app.exception_handler(StarletteHTTPException)  # 重写HTTPException异常处理器
async def http_exception_handler(request, exc):
    print(f"全局异常:{request.method}URL{request.url}Headers:{request.headers}{traceback.format_exc()}")
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)

上面的第一个函数就是重写的参数校验的处理器,返回PlainTextResponse信息的同时会在控制台打印具体错误;

上面的第二个函数就是重写的HTTPException异常的处理器,同样返回PlainTextResponse信息的同时会在控制台打印具体错误;

  • 参数校验

这部分不需要重新写操作函数,找到之前写的某一个请求,发送错误类型的错误就会抛出异常:

image-20221203170053064

image-20221203170120577

image-20221203165215816

  • HTTPException
@app08.get("/stu08/Request_Validation_Error/{param}")
async def stu08_request_validation_error(param: int):
    if param != 2:
        raise HTTPException(detail="请输入MinChess!", status_code=410)
    return {"param": param}

新建一个请求,用本章第一个例子也可以,上面的代码就表示当输入的param不为2时,抛出HTTPException异常:

image-20221203164912237

image-20221203164845563

源码

项目结构如下图,具体的配置可以参看下面文章的第二节:

https://blog.jiumoz.com/archives/fastapi-cong-ru-men-dao-shi-zhan-13-chang-jian-pei-zhi-xiang

image-20221203163907997

  • exception.py
# -*- coding: utf-8 -*-
# @Time: 2022/12/2 16:28
# @Author: MinChess
# @File: exception.py
# @Software: PyCharm
class UnicornException(Exception):
    def __init__(self, name: str):
        self.name = name
  • main.py
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse, PlainTextResponse, HTMLResponse
from fastapi.exceptions import RequestValidationError
from fastapi.staticfiles import StaticFiles
from stu import app01, app02, app03, app04, app05, app06, app07, app08
import uvicorn
import traceback
from utils import exception # 导入类
from starlette.exceptions import HTTPException as StarletteHTTPException

app = FastAPI(
    # 创建一个FastAPI实例\这里的变量 app 会是 FastAPI 类的一个「实例」。\这个实例将是创建你所有 API 的主要交互对象。\这个 app 同样在命令中被 uvicorn 所引用:
    title='FastAPI学习教程文档——title',
    description='这是FastAPI教程的文档——description',
    version='1.0.0',
    docs_url='/docs',
    redoc_url='/redoc',
)

app.mount(path="/static", app=StaticFiles(directory='./static'), name='static')


@app.exception_handler(exception.UnicornException) # 用@app.exception_handler() 为UnicornException添加自定义异常控制器
async def unicorn_exception_handler(request: Request, exc: exception.UnicornException):
    """
    :param request: 请求头
    :param exc: 异常对象
    :return:
    """
    print(f"全局自定义异常:method:{request.method} URL:{request.url}Headers:{request.headers}")
    return JSONResponse(
        status_code=418,
        content={
            "message": f"你输入的: {exc.name} 是错的!!!"
        }
    )


@app.exception_handler(RequestValidationError)  # 重写请求验证异常处理器
async def request_validation_exception_handler(request: Request, exc: RequestValidationError):
    """
    请求参数验证异常
    :param request: 请求头信息
    :param exc: 异常对象
    :return:
    """
    # 日志记录异常详细上下文
    print(f"全局异常:{request.method}URL{request.url}Headers:{request.headers}{traceback.format_exc()}")
    return PlainTextResponse(str(exc), status_code=400)


@app.exception_handler(StarletteHTTPException)  # 重写HTTPException异常处理器
async def http_exception_handler(request, exc):
    print(f"全局异常:{request.method}URL{request.url}Headers:{request.headers}{traceback.format_exc()}")
    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
  • stu08.py
# -*- coding: utf-8 -*-
# @Time: 2022/12/1 14:55
# @Author: MinChess
# @File: stu08.py
# @Software: PyCharm
from fastapi import APIRouter, HTTPException, Path,Body
from fastapi.exceptions import RequestValidationError
from fastapi.encoders import jsonable_encoder
from typing import Optional, List
from pydantic import Field
from utils import UnicornException
from pydantic import BaseModel
from datetime import datetime

app08 = APIRouter()


# 抛出HTTPException
@app08.get("/stu08/{id}")
def stu08_get_error(
        id: str = Path(...)
):
    if id != "MinChess":
        return HTTPException(status_code=404, detail="not found")
    return {
        "name": "MinChess",
        "age": 22,
        "Blog": "https://blog.jiumoz.com"
    }


# 添加自定义响应头
@app08.get("/stu08/header/{id}")
def stu08_get_error_header(
        id: str
):
    if id != "MinChess":
        raise HTTPException(
            status_code=404,
            detail="Not Found",
            headers={"X-Error": "There gose my error."}
        )
    return {
        "name": "MinChess",
        "age": 22,
        "Blog": "https://blog.jiumoz.com"
    }


# Theere id MinChess's python pro
# 自定义异常处理器

@app08.get("/stu08/custom/{name}")
async def stu08_custom(
        name: str = Path(default="MinChess")
):
    if name == "MinChess":
        raise UnicornException(name=name)
    return {"name": "MinChess"}


@app08.get("/stu08/Request_Validation_Error/{param}")
async def stu08_request_validation_error(param: int):
    if param != 2:
        raise HTTPException(detail="请输入MinChess!", status_code=410)
    return {"param": param}


感谢阅读!

九陌斋地址:https://blog.jiumoz.com/archives/fastapi-cong-ru-men-dao-shi-zhan-12-cuo-wu-chu-li

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FastAPI从入门到实战(12)——错误处理 的相关文章

随机推荐

  • Android中的ConstraintLayout约束布局

    ConstraintLayout约束布局 ConstraintLayout有啥好处呢 可以减少布局层次 特别适合复杂的大型布局 可谓是集线性布局和相对布局于一身的荣誉布局 使用 添加依赖 目前 AndroidStudio新的版本默认就给你上
  • MMdetection3D学习系列(二)——KITTI数据集训练测试及可视化

    安装完环境以后 就可以进行测试了 这里我使用的是KITTI数据集进行测试 关于KITTI数据集 网上有很多介绍了 这里简单说一下在mmdet3d中它需要的文件层级样式吧 主要是针对RGB和点云数据进行检测 一般来说采用其中一侧的彩色摄像头的
  • centos7重启或关机卡死

    这个问题其实是systemd219这个版本的问题 查看systemd版本 请使用systemctl version 由于systemd进程的判断比之前更加严格 如果某些进程不响应SIGTERM信号 可能会导致重启是挂死 该问题和业务进程对S
  • Ubuntu查看安装的软件、.开头的文件

    1 dpkg l grep 比如 dpkg l grep libjansson4 2 show hidden files那里
  • Spring整合mybatis和Junit单元测试

    1 Spring整合mybatis 前提了解 spring 管理 mybatis mybatis 管理 mapper 要依赖于德鲁伊连接池 spring 管理sqlsessionfactory 思路 Spring整合Mybatis主要做两件
  • Vue极简使用2

    Vue极简使用 Vue基础内容 模板语法 解析文本 解析原始HTML 动态属性 模板语法使用限制 条件渲染 列表渲染 事件处理 列表渲染 事件处理 修饰符 表单输入绑定 计算属性 样式处理 表单输入和绑定 修饰符 计算属性和监听器 计算属性
  • 差分详细讲解(C++)

    每日一句 平凡的我在人多的地方曾极力小心翼翼 但不知从何时起 我不太在意别人的目光了 比起被人觉得是个怪人 我现在更害怕浪费时间 差分 一 一维差分 二 二维差分 一 一维差分 差分就是前缀和的逆运算 如果你不懂什么是前缀和 看这里 gt
  • Ubuntu20.04下解决Qt出现qt.qpa.plugin:Could not load the Qt platform plugin “xcb“ 问题

    问题描述 python调用matplotlib pyplot库进行图形绘制时弹出错误提示 qt qpa plugin Could not load the Qt platform plugin xcb in even though it w
  • (个人)AR电子书系统创新实训第五周(1)

    服务器上传大文件的问题 在搭建并使用了云服务器后 我遇到了一个奇怪的问题 如果上传的文件中包含了视屏的话 上传就会失败 同时返回一个402error页面 一开始 我以为是文件类型的问题 通过网上查找后 我发现问题依然在于服务器本身的设置上
  • linux学习lesson14

    目录 1 df命令 2 du命令 3 磁盘分区 1 df命令 命令df disk filesystem的简写 用于查看已挂载磁盘的总容量 使用容量 剩余容量等 可以不加任何参数 默认以KB为单位显 i 表示查看inodes的使用状况 如已使
  • zookeeper环境构建

    关于zookeeper的作用这里不再作详述 相信很多开发人员在很多场景都使用zookeeper作为任务协调 1 安装jdk 这里不述详述 下载jdk压缩包 并在 etc profile中增加相关的环境变量配置 export JAVA HOM
  • python各个版本区别_Python 的各个版本

    Python 现在用的最多的就是两个版本 Python 2 x 系列 以及一个较新的 Python 3 x 系列 Python 3 x 系列是开始于2008年的十二月的 3 0 版本 从这个版本发布开始 Python 2 7 之后就只有小版
  • 解决Jetbrains旗下产品的插件下载失败问题(IntelliJ IDEA、RubyMine、WebStorm、PhpStorm、PyCharm、AppCode、Android Studio等)

    博主主要关注IntelliJ IDEA插件 使用时安装超时 解决办法其实很简单 进入Jetbrains官方插件仓库地址 https plugins jetbrains com 选择你所用的开发工具 然后在左上角搜索框搜索你需要的插件 搜索后
  • JDK1.8 之Stream API总结

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Stream是 Java 8新增加的类 用来补充集合类 Stream代表数据流 流中的数据元素的数量可能是有限的 也可能是无限的 Stream和其它集合类的区别在于 其它集
  • mysql insert into多条_MySql中使用INSERT INTO语句更新多条数据的例子

    我们知道当插入多条数据的时候insert支持多条语句 复制代码 代码如下 INSERT INTO t member id name email VALUES 1 nick nick 126 com 4 angel angel 163 com
  • 如何解决:FileNotFoundError: 以及[Errno 2]No such file or directory

    出错原因 因为种种问题系统无法找到对应路径的文件 案例如下 我在pycharm的目录下新建了一个apple txt文件 想通过open 获取到对应文件里面的内容 结果提示 Errno 2 No such file or directory
  • Spark环境搭建部署全流程(Linux),看这一篇就够了

    前言 本篇文章将给各位展示如何快速地在linux上搭建spark 本文搭建的环境为Vmware 16 pro 下的CentOS 7 linux hadoop版本为3 x以上 Jdk1 8 以下是我总结出的spark几种模式的部署流程 如果是
  • 原来游戏技术行业最大的秘密竟然是...

    欢迎大家前往腾讯云 社区 获取更多腾讯海量技术实践干货哦 本文由腾讯游戏云发表于云 社区专栏 本篇文章主要是分享游戏业务面临的安全风险场景 以及基于这些场景的特点 我们应该如何做好对应的防护 一 背景 游戏行业DDoS攻击愈演愈烈 2017
  • Python模块multiprocessing & 实现多进程并发

    简介 multiprocessing模块是Python标准库中提供的一个用于实现多进程编程的模块 它基于进程而不是线程 可以利用多核CPU的优势 提高程序的执行效率 同时也可以实现进程间通信和数据共享 目录 1 参数说明 1 1 Proce
  • FastAPI从入门到实战(12)——错误处理

    错误提示是非常重要的 比如权限控制 资源控制等场景 需要服务器返回给用户错误提示 包括状态码和提示等内容 所以本文就主要记录FastAPI里的错误处理相关的内容 抛出一个HTTPException app08 get stu08 id de