首页 文章

处理Flask路线中的所有异常

提问于
浏览
-1

我的Flask应用程序中有一条简单的路线:

@app.route('/', methods=['GET'])
def homepage():
    return '{}'.format(1 / 0)

当用户访问site.com/时,她应该看到1/0的结果 . 当然这是不可能的,所以Python给我一个错误 .

现在,我希望以特殊方式处理所有 endpoints 上的所有错误:我希望它们返回JSON响应,例如:

{
    'status_code': 500,
    'status': 'Internal Server Error'
}

我写了一个装饰器来完成这个:

def return_500_if_errors(f):
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except:
            response = {
                'status_code': 500,
                'status': 'Internal Server Error'
            }
            return flask.jsonify(response), 500
    return wrapper

然后我将装饰器添加到 endpoints :

@return_500_if_errors
@app.route('/', methods=['GET'])
def homepage():
    return '{}'.format.(1 / 0)

但是,装饰器似乎没有任何效果 .

3 回答

  • 0

    这就是你需要的:

    from flask import Flask, jsonify
    from functools import wraps
    
    app = Flask(__name__)
    
    def catch_custom_exception(func):
        @wraps(func)
        def decorated_function(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except Exception as e:
                return str(e), 500
        return decorated_function
    
    @app.route('/', methods=['GET'])
    @catch_custom_exception
    def homepage():
        return '{}'.format(1 / 0)
    
    @app.route('/2', methods=['GET'])
    def homepage2():
        return '{}'.format(1 / 0)
    
  • 0

    正如@YiFei和@Joost所指出的那样,问题在于装饰器的顺序 .

    这确实有效:

    def return_500_if_errors(f):
        def wrapper(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except:
                response = {
                    'status_code': 500,
                    'status': 'Internal Server Error'
                }
                return flask.jsonify(response), 500
        return wrapper
    
    @app.route('/', methods=['GET'])
    @return_500_if_errors
    def homepage():
        return '{}'.format.(1 / 0)
    

    @ Joost的答案是类似的,但不知何故不同,因为它是错误本身被捕获和返回 - 而不是标准化的JSON .

  • 0

    我强烈建议使用Flask的error handler已经存在的装饰器 .

    基本上,应该看起来像:

    # flask will check if raised exception is of type 'SomeException' (or lower)
    # if so, will just execute this method
    @app.errorhandler(SomeException) 
    def handle_error(error):
        response = jsonify(error.to_dict())
        response.status_code = error.status_code
        return response
    
    # An exception will be raised, hopefully to be caught by 'handle_error'    
    @app.route('/', methods=['GET'])
    def homepage():
        return '{}'.format.(1 / 0)
    

    只要确保要捕获的异常将具有'status_code'或者如果不是,则将'500'放入...

相关问题