18.FastAPI错误处理

18.1 HTTPException

当我们需要在FastAPI中返回错误时,可以使用HTTPException返回错误信息。HTTPException是包含了与API相关数据的Python异常,所以在程序需要raise,而不是return。 HTTPException的参数包括:

  • status_code 状态码
  • detail 详细信息,可以使用能够转换为JSON格式的任何数据类型,不止于str
  • headers 自定义响应头

代码示例:


# coding: utf-8
from fastapi import FastAPI
from fastapi import HTTPException

app = FastAPI()

langs = {
    'python': 'Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。',
    'go': 'Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。'
}

@app.get(path='/language/{lang_name}')
def language(lang_name: str):
    if lang_name not in langs:
        raise HTTPException(
            status_code=404,
            detail={'Error': 'The language not found.'},
            headers={'X-Error': 'The language not found.'}
        )
    return langs[lang_name]


执行请求:


curl http://127.0.0.1:8000/language/python -i
HTTP/1.1 200 OK
date: Tue, 01 Feb 2022 08:07:46 GMT
server: uvicorn
content-length: 478
content-type: application/json

"Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。"


上面的请求是一个返回正确结果的请求。下面执行一个返回错误的请求:


curl http://127.0.0.1:8000/language/c -i
HTTP/1.1 404 Not Found
date: Tue, 01 Feb 2022 08:08:48 GMT
server: uvicorn
x-error: The language not found.
content-length: 46
content-type: application/json

{"detail":{"Error":"The language not found."}}


18.2自定义异常处理

在FastAPI中,可以根据用户的需求进行自定义异常的封装和处理,对于自定义异常首先需要定义一个继承自Exception的自定义异常类,然后使用 @app.exception_handler() 添加自定义异常控制器。这样就可以在路由方法中raise相应的异常进行响应。

代码示例:


# coding: utf-8
from fastapi import FastAPI
from fastapi import Request
from fastapi.responses import JSONResponse

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

app = FastAPI()

@app.exception_handler(LangException)
async def lang_exception_handle(request: Request, ex: LangException):
    return JSONResponse(
        status_code=418,
        content='Not found the language: %s' % ex.name
    )

langs = {
    'python': 'Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。',
    'go': 'Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。'
}

@app.get(path='/language/{lang_name}')
def language(lang_name: str):
    if lang_name not in langs:
        raise LangException(lang_name)
    return langs[lang_name]


执行请求:


curl http://127.0.0.1:8000/language/python -i
HTTP/1.1 200 OK
date: Tue, 01 Feb 2022 08:26:33 GMT
server: uvicorn
content-length: 478
content-type: application/json

"Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。"

curl http://127.0.0.1:8000/language/c -i
HTTP/1.1 418
date: Tue, 01 Feb 2022 08:26:39 GMT
server: uvicorn
content-length: 27
content-type: application/json

"Not found the language: c"


从以上示例可以看出,当请求http://127.0.0.1:8000/language/c时,由于找不到c语言的说明,所以触发LangException异常,该异常将被lang_exception_handle方法处理。