JessePinkmen 2020-07-26
flask_restful的错误处理一直感觉有点混乱,官方文档写的也不清不楚的,所以自己写了一个小样来测试一下。
api = Api()
app = Flask(__name__)
flask_restful版本:0.3.8
分为以下几种情况:
1.404,有两种情况,一种是路由匹配不存在,就是没有这样的url;还有一种是主动abort(404)。api的catch_all_404s如果是True,两种使用的都是flask_restful内置的异常处理,否则,只有主动的abort(404)使用,另一种则使用在app中定义的404处理
2.abort, 在app中定义的都是无效的。在flask视图中使用abort,会转到flask的错误处理中,但是在flask_restful就不行了。还不知道在flask_restful中怎么加入错误码处理。
3.HTTPException: werkzeug.exceptions中的异常,也是flask中的默认异常。对于这类异常和继承的异常,flask_restful对此有特殊的处理,返回的数据格式为{"message":"xxxxxxxxx"},message为该异常的description,http状态码就是该异常的code属性。可以在初始化时传入response=Resonse("xxxxx"),这样就会返回这个。诡异的是,在api的errors加入这个异常,返回时是html格式的并且非常奇怪的样式。后来在源代码中发现了这个:
error_cls_name = type(e).__name__ if error_cls_name in self.errors: custom_data = self.errors.get(error_cls_name, {}) code = custom_data.get(‘status‘, 500) data.update(custom_data)
在errors中该异常的对应返回值字典中加入status属性作为状态码,就能正常返回。但是这个异常本身的code就不能使用了。如果不这么写,在异常中加入data={}也可以自定义返回。
4.errors。这是官方文档中推荐的写法,在api初始化时传入:Api(errors=errors)。但是我个人觉得,不是很好用。不够灵活,与上面的HTTPExcetion一样,都需要status参数才能运行,而且获得的数据比较静态,在初始化阶段就已经固定了,好像不能够使用异常中的数据。
5.其他。对于flask_restful无法正确处理的异常,会往上raise。这样就可以通过在app中定义异常处理,第一个404大概就是这种原理。
flask_restful的开发者已经在github上推广其他的替代品。作者原话:
As some folks have noticed, I don‘t work on this much anymore. This is mostly because I‘ve found alternatives that I like better than what‘s provided here, so I don‘t actively use Flask-RESTful for any of my projects anymore.
Here‘s what I recommend for replacements in TL;DR form:
Resource
→ Regular flaskMethodView
reqparse
→ webargs/Marshmallowfields
→ Flask-Marshmallowutils.cors
→ Flask-CORSutils.crypto
→ Nobody knows what this even doesMarshmallow in particular is a worthwhile change because it does so many things better than
fields
orreqparse
:
- It can parse nested objects and lists from requests
- better type support
- It has better and more flexible validation
- better API in general. Schemas are objects that can inherit other schemas for composability
Regarding
Resource
I found that I did not need any of the wrapping that it andApi
do. JustMethodView
from Flask was plenty for any use case I found.
看样子作者似乎不再打算积极维护这个拓展,评论里也有不少人推荐了其他的类似拓展。