【问题标题】:Handle an error from flask decorator处理来自烧瓶装饰器的错误
【发布时间】:2018-08-11 05:05:32
【问题描述】:

我有一个与装饰器有关的问题。例如我写了下一个装饰器,它处理错误,然后输出错误。

def handle_error(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as err:
            print(err)
    return wrapper


@handle_error
def raise_error():
    return 1 / 0

raise_error()

但是,如果我想对 Flask 做同样的事情,那就行不通了。

@app.route('/')
@handle_error
def index():
    return {'hello'}

if __name__ == '__main__':
    app.run()

所以我猜,route 装饰器中引发的错误,对吗?如果是,我有一个问题:从技术上讲,我可以编写一个装饰器来处理来自 route 装饰器的所有异常?

【问题讨论】:

  • 您的 index() 视图函数没有引发任何错误(返回 set 不是错误),我们这样的自定义错误处理程序没有引发任何异常。您希望看到什么错误?
  • index() 函数,也将被route 装饰器调用,在这条路线中我们会得到错误,实际上这是我需要的。通过装饰器控制任何烧瓶错误。

标签: python flask error-handling python-decorators


【解决方案1】:

你可以像我在我的装饰器中那样创建一个错误处理程序

def error_handler() -> object:
    def wrapper(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            # handle different types of errors and return messages accordingly with status code
            except Exception as e:
                if isinstance(e, ValueError):
                    return jsonify({'message': e.args[0], 'type': 'ValueError'}), 400
                elif isinstance(e, AttributeError):
                    return jsonify({'message': e.args[0], 'type': 'AttributeError'}), 400
                elif isinstance(e, KeyError):
                    return jsonify({'message': e.args[0], 'type': 'KeyError'}), 400
                elif isinstance(e, TypeError):
                    return jsonify({'message': e.args[0], 'type': 'TypeError'}), 400
                else:
                    return jsonify({'message': str(e), 'type': 'InternalServerError'}), 500
        return wrapped
    return wrapper

如果您希望将这些错误记录在文件中,您可以在我们初始化烧瓶应用程序的位置导入并设置日志记录。日志消息,以及来自 except 块的错误。

【讨论】:

    【解决方案2】:

    Flask 已经有了 errorhandler() 装饰器,look here for a quick introduction

    你不会用它来装饰你的视图函数,而是用它来装饰你想要的错误处理函数。

    以您的示例代码为例,使用此装饰器可能如下所示:

    @app.route('/')
    def index():
        return {'hello'}
    
    @app.route('/dividebyzero')
    def divbyzero():
        return 1 / 0
    
    @app.errorhandler(404):
    def handle_notfound(e):
        return 'we could not find the page'
    
    @app.errorhandler(500):
    def handle_intsrverr(e):
        return 'we stumbled upon some exception'
    
    if __name__ == '__main__':
        app.run()
    

    【讨论】:

    • 谢谢!我知道error_handler,但我正在寻找一些不同的东西,例如我需要写一个decorator,它将处理错误并写入log.files,或者这个,所以,我需要创建自己的处理程序来处理错误,并拥有一个流等,并且不会引发任何 HTTP 错误。
    【解决方案3】:

    您可以将错误处理程序与记录器一起使用。

    logger = app.logger()
    
    @app.errorhandler(500)
    def somehandler(e):
        logger.critical(e.description) # this is level of logger
    

    所以当 500 错误发生时,记录器将工作。 你也可以自己犯错误。

    How can I implement a custom error handler for all HTTP errors in Flask?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 2021-06-04
      • 2016-03-11
      • 1970-01-01
      相关资源
      最近更新 更多