# 前言
最近在用一个flask的校验框架:flask_pydantic,但是他的返回格式是固定的,大概如下,且框架自动处理了validate报错,就让flask的handerror捕捉不到他,让人很头疼,比如对我自己来说可能就不想返回url这个字段
{
"validation_error": {
"body_params": [
{
"input": {
"descri1ption": "11"
},
"loc": [
"name"
],
"msg": "Field required",
"type": "missing",
"url": "https://errors.pydantic.dev/2.3/v/missing"
},
{
"input": {
"descri1ption": "11"
},
"loc": [
"description"
],
"msg": "Field required",
"type": "missing",
"url": "https://errors.pydantic.dev/2.3/v/missing"
}
]
}
}
然后他一共有四种校验参数:body_params,form_params,path_params,query_params,如果有值就返回,如果没有就不返回
# 方法
话不多说直接上操作:
通过查看flask_pydantic\core.py第238行可以发现他的错误处理机制是
1. 如果 `err` 存在,说明出现了 Pydantic 校验错误。
2. 如果 `FLASK_PYDANTIC_VALIDATION_ERROR_RAISE` 设置为 True,那么程序会抛出 `FailedValidation` 异常,并将校验错误信息作为异常的参数传递给异常类。
3. 如果 `FLASK_PYDANTIC_VALIDATION_ERROR_RAISE` 设置为 False,那么程序会读取 `FLASK_PYDANTIC_VALIDATION_ERROR_STATUS_CODE` 配置选项来确定返回的 HTTP 状态码,默认为 400。然后,程序会使用 Flask 的 `make_response` 和 `jsonify` 方法来生成响应对象,将校验错误信息作为 JSON 数据放到响应体中,并返回给客户端。(这里就是我前文说的他自动处理了异常,导致handerror捕捉不到)
if err:
if current_app.config.get(
"FLASK_PYDANTIC_VALIDATION_ERROR_RAISE", False
):
raise FailedValidation(**err)
else:
status_code = current_app.config.get(
"FLASK_PYDANTIC_VALIDATION_ERROR_STATUS_CODE", 400
)
return make_response(
jsonify({"validation_error": err}),
status_code
)
然后在第十四行可以看到FailedValidation是来自于.exception
```python
from .exceptions import ValidationError as FailedValidation
```
所以我们可以在app.config设置FLASK_PYDANTIC_VALIDATION_ERROR_RAISE为True,然后再用handerror(ValidationError),就能捕获他抛出的异常了!如下
from flask_pydantic.exceptions import ValidationError
app = Flask(__name__)
app.config['FLASK_PYDANTIC_VALIDATION_ERROR_RAISE']=True
@app.errorhandler(ValidationError)
def validation_execution_handler(error):
#捕捉flask_pydantic 的 validate()返回的错误,并且重写返回值(方便前端msg)
body_params = error.body_params
form_params = error.form_params
path_params = error.path_params
query_params = error.query_params
msg = {}
if body_params is not None:
msg["body_params"] = [{k:v for k,v in params.items() if k != 'url' } for params in body_params]
if form_params is not None:
msg["form_params"] = [{k:v for k,v in params.items() if k != 'url' } for params in form_params]
if path_params is not None:
msg["path_params"] = [{k:v for k,v in params.items() if k != 'url' } for params in path_params]
if query_params is not None:
msg["query_params"] = [{k:v for k,v in params.items() if k != 'url' } for params in query_params]
return jsonify({
"code": 400,
"msg": msg
}), 400
validation_execution_handler(error):这一段代码可能有瑕疵,本文主要介绍如何捕捉flask_pydantic异常并自定义返回,如果觉得有用的话还请点赞