关于flask_restful的异常处理

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:

Marshmallow in particular is a worthwhile change because it does so many things better than fields or reqparse:

  • 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 and Api do. Just MethodView from Flask was plenty for any use case I found.

看样子作者似乎不再打算积极维护这个拓展,评论里也有不少人推荐了其他的类似拓展。

相关推荐