提出问题
参数校验返回都是英文
默认参数校验,报错信息都是英文的,中国用户看不懂
返回格式与开发习惯不符合
改为更符合习惯的格式,如下:
{
"code": 40001,
"msg": "请求参数校验失败",
"errors": [
{
"field": "path.name",
"message": "输入内容太短,应该大于 2 个字符"
}
]
}
创建异常处理文件
创建目录
在 main.py 文件的同级,创建 core 目录
创建文件
在 core 目录下创建 exceptions.py 文件,内容如下:
from fastapi import Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
# 翻译字典:key是pydantic error type,稳定,版本升级不会变
VALIDATION_I18N = {
"int_parsing": "请输入合法整数",
"float_parsing": "请输入合法浮点数",
"greater_than_equal": "输入应该大于等于 {ge}",
"greater_than": "输入应该大于 {gt}",
"less_than_equal": "输入应该小于等于 {le}",
"less_than": "输入应该小于 {lt}",
"string_too_short": "输入内容太短,应该大于 {min_length} 个字符",
"string_too_long": "输入内容太长,应该小于 {max_length} 个字符",
"string_pattern_mismatch": "格式不满足规则:{pattern}",
"missing": "此字段必填",
"bool_parsing": "只能传 true / false / 1 / 0",
}
async def validation_error_handler(request: Request, exc: RequestValidationError):
err_list = []
for err in exc.errors():
field_path = ".".join(map(str, err["loc"]))
err_type = err["type"]
ctx = err.get("ctx", {})
zh_msg = VALIDATION_I18N.get(err_type, f"参数错误:{err_type}")
# 填充占位符,例如 {ge} {le} {pattern}
try:
zh_msg = zh_msg.format(**ctx)
except KeyError:
pass
err_list.append({
"field": field_path,
"message": zh_msg
})
return JSONResponse(
status_code=422,
content={
"code": 40001, # 业务自定义错误码
"msg": "请求参数校验失败",
"errors": err_list
}
)
修改main.py
调用 app.add_exception_handler() 函数,将上面的 validation_error_handler 传进去:
from fastapi import FastAPI
from fastapi.params import Path
from core.exceptions import validation_error_handler
from fastapi.exceptions import RequestValidationError
app = FastAPI()
app.add_exception_handler(RequestValidationError, validation_error_handler)
完整代码
from fastapi import FastAPI
from fastapi.params import Path
from core.exceptions import validation_error_handler
from fastapi.exceptions import RequestValidationError
app = FastAPI()
app.add_exception_handler(RequestValidationError, validation_error_handler)
# @app.get('/student/{age}')
# async def update_student(age: int=Path(...,ge=10,le=120)):
# print("age:", age)
# return {'msg': '更新成功!'}
# @app.get('/student/{age}')
# async def update_student(age: int=Path(...,ge=10,le=120,description="年龄大于等于10岁,小于等于120岁")):
# print("年龄:", age)
# return {'msg': '更新成功!'}
@app.get('/student/{name}')
async def get_student(name: str=Path(...,min_length=2,max_length=3)):
if name == '李雷':
student = {
'name': '李雷',
'age': 21,
}
else:
student = {
'message': '没有此学号的学生',
}
return student
测试
参数过短错误
访问:http://127.0.0.1:8000/student/李 ,浏览器显示如下:
{
"code": 40001,
"msg": "请求参数校验失败",
"errors": [
{
"field": "path.name",
"message": "输入内容太短,应该大于 2 个字符"
}
]
}
参数过长错误
访问:http://127.0.0.1:8000/student/lili ,浏览器显示如下:
{
"code": 40001,
"msg": "请求参数校验失败",
"errors": [
{
"field": "path.name",
"message": "输入内容太长,应该小于 3 个字符"
}
]
}