尝试块中的Flask abort()行为

7
当我想在try块内使用Flask abort时,最终会进入我的异常块。
@app.route('/newsletters/<int:newsletter_id>', methods=['GET'])
def route_get_newsletter(newsletter_id):
    if request.method == 'GET':        
        try:
            newsletter = get_newsletter(newsletter_id)                
            if not newsletter:
               abort(404)
        except Exception, ex:
            logging.exception("Something awful happened!")
            abort(500)
        else:            
            return jsonify(newsletter=newsletter)

输出结果为:

ERROR:root:Something awful happened!
Traceback (most recent call last):
 File "natuurpuntapi.py", line 210, in route_get_newsletter
   abort(404)
 File "/usr/lib/python2.7/dist-packages/werkzeug/exceptions.py", line 525, in __call__
   raise self.mapping[code](*args, **kwargs)
NotFound: 404: Not Found

当调用werkzeug NotFound时,我会得到500响应。

当我将abort(404)放在try块外面时,它起作用并返回404响应。

  • 编辑

我发现flask abort()使用werkzeug abort(),这是一个名为Aborter()的类。当调用此函数时,它会引发"raise self.mapping[code](*args, **kwargs)"

这是否意味着我不能在自己的try块中调用abort,因为它会引发异常并进入我的异常处理程序?


你能分享一下 get_newsletter(newsletter_id) 函数的代码吗?在该函数内如何处理异常情况? - codegeek
2个回答

11

flask.abort(...)会引发一个异常,这个异常是在文档中描述的所有werkzeug.exceptions.HTTPException的子类之一。这就是为什么你的代码不起作用的原因。

但是还有其他一些有趣的小知识:

有了这些知识,我们可以重写你的代码如下:

@app.route('/newsletters/<int:newsletter_id>', methods=['GET'])
def route_get_newsletter(newsletter_id):
    newsletter = get_newsletter(newsletter_id)
    return jsonify(newsletter=newsletter)

@app.errorhandler(500)
def catch_server_errors(e):
    logging.exception("Something awful happened!")

马库斯,你的解决方案有效。但是为什么抛出错误可以解决问题呢? - user1120753
我重新写了我的回答。这样好一些吗? - Markus Unterwaditzer
这一定是因为天气太热了 :) - 我现在明白了 - user1120753

8
您可以检查错误是否来自HTTPException,然后访问.code属性。
from werkzeug.exceptions import HTTPException

@app.route('/newsletters/<int:newsletter_id>')
def route_get_newsletter(newsletter_id):
    try:
        newsletter = get_newsletter(newsletter_id)                
        if not newsletter:
            abort(404)
    except Exception as e:
        if isinstance(e, HTTPException):
            abort(e.code)
        else:
            abort(500)
    return jsonify(newsletter=newsletter)


这是2021年,这是一个更优雅的解决方案。 - Ananta K Roy
如果您在使用类似abort(404, "用户未找到")这样的消息时,那么您可以在第11行中使用abort(e.code, e.data["message"])而不是abort(e.code)。注意:如果您没有在第一次加载时填充自定义消息,这将引发错误。 - K14

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接