FastAPI from entry to actual combat (12) - error handling

Error prompts are very important. For scenarios such as permission control and resource control, the server needs to return error prompts to users, including status codes and prompts. Therefore, this article mainly records the content related to error handling in FastAPI.

throws an 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"
    }

fastapiImport from it HTTPException, and judge the output in the path operation function;

The above code is to throw an error when the input idis wrong , the error code is , and the detailed information isMinChess404not found

image-20221203164124803

Add custom response headers

@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"
    }

In some scenarios, the front end may need to HTTPadd some custom response headers to the error. The adding method is as above, and it can be set HTTPExceptiondirectly headers;

image-20221203164434584

custom exception handler

Define a Exceptiontype error class UnicornException, which corresponds to login failure errors, verification code errors, etc. in practical applications;

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

Define the error handling function in the main application UnicornException. If it is not in the same file, you need to import the corresponding class. Refer to the source code at the end of the article;

@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} 是错的!!!"
        }
    )

Just declare in the application, and import related classes;

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

The above function is to throw an error when the name entered by the user is MinChess UnicornException; if the error handling function here needs to implement global processing, it must be mounted on the Taoist application;

According to the above processing function, MinChesswhen we operate the input, it will not only return the predetermined data to the front end, but also output relevant information on the console, as follows:

image-20221203164558523

image-20221203164641276

override default exception handler

Rewriting the default exception handler is to artificially intervene the default exception built in fastapi. The method is very simple, just rewrite it as the above method;

@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)

The first function above is the rewritten parameter verification processor, which PlainTextResponsewill print specific errors on the console while returning information;

The second function above is the rewritten HTTPException exception handler, which also returns PlainTextResponseinformation and prints specific errors on the console;

  • Parameter check

This part does not need to rewrite the operation function. If you find a request written before and send an error of the wrong type, an exception will be thrown:

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}

To create a new request, you can also use the first example in this chapter. The above code means that when the input is paramnot 2, HTTPExceptionan exception is thrown:

image-20221203164912237

image-20221203164845563

source code

The project structure is as shown in the figure below. For specific configuration, please refer to the second section of the following article:

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}


Thanks for reading!

Jiumozhai Address: https://blog.jiumoz.com/archives/fastapi-cong-ru-men-dao-shi-zhan-12-cuo-wu-chu-li

Guess you like

Origin blog.csdn.net/qq_45730223/article/details/128167219