处理 Flask 路由中的所有异常
Handle all exceptions in Flask route
我的 Flask 应用程序中有一条简单的路线:
@app.route('/', methods=['GET'])
def homepage():
return '{}'.format(1 / 0)
当用户访问 site.com/ 时,她应该看到 1/0 的结果。当然那是不可能的,所以 Python 抛出一个错误。
现在,我希望以特殊方式处理我所有端点上的所有错误:我希望它们 return 一个 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
然后我将装饰器添加到端点:
@return_500_if_errors
@app.route('/', methods=['GET'])
def homepage():
return '{}'.format.(1 / 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)
正如@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.
我强烈建议使用 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'...
我的 Flask 应用程序中有一条简单的路线:
@app.route('/', methods=['GET'])
def homepage():
return '{}'.format(1 / 0)
当用户访问 site.com/ 时,她应该看到 1/0 的结果。当然那是不可能的,所以 Python 抛出一个错误。
现在,我希望以特殊方式处理我所有端点上的所有错误:我希望它们 return 一个 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
然后我将装饰器添加到端点:
@return_500_if_errors
@app.route('/', methods=['GET'])
def homepage():
return '{}'.format.(1 / 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)
正如@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.
我强烈建议使用 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'...