有没有办法添加一个全局的catch-all错误处理程序,我可以在其中更改对通用JSON响应的响应?
我无法使用got_request_exception
信号,因为不允许修改回复(http://flask.pocoo.org/docs/0.10/signals/)。
相比之下,所有信号处理程序都以未定义的顺序执行,不会修改任何数据。
我宁愿不包装app.handle_exception
函数,因为它感觉像内部API。我想我的事情就像:
@app.errorhandler()
def handle_global_error(e):
return "Global error"
请注意errorhandler
不带任何参数,这意味着它会捕获所有没有附加特定错误处理程序的异常/状态代码。我知道我可以使用errorhandler(500)
或errorhandler(Exception)
来捕获异常,但如果我执行abort(409)
,它仍会返回HTML响应。
答案 0 :(得分:45)
您可以使用@app.errorhandler(Exception)
:
Demo(HTTPException检查确保保留状态代码):
from flask import Flask, abort, jsonify
from werkzeug.exceptions import HTTPException
app = Flask('test')
@app.errorhandler(Exception)
def handle_error(e):
code = 500
if isinstance(e, HTTPException):
code = e.code
return jsonify(error=str(e)), code
@app.route('/')
def index():
abort(409)
app.run(port=1234)
输出:
$ http get http://127.0.0.1:1234/
HTTP/1.0 409 CONFLICT
Content-Length: 31
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:54 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "409: Conflict"
}
$ http get http://127.0.0.1:1234/notfound
HTTP/1.0 404 NOT FOUND
Content-Length: 32
Content-Type: application/json
Date: Sun, 29 Mar 2015 17:06:58 GMT
Server: Werkzeug/0.10.1 Python/3.4.3
{
"error": "404: Not Found"
}
如果您还想覆盖Flask中的默认HTML异常(以便它们也返回JSON),请在app.run
之前添加以下内容:
from werkzeug.exceptions import default_exceptions
for ex in default_exceptions:
app.register_error_handler(ex, handle_error)
对于较旧的Flask版本(< = 0.10.1,即目前任何非git / master版本),请将以下代码添加到您的应用程序中以明确注册HTTP错误:
from werkzeug import HTTP_STATUS_CODES
for code in HTTP_STATUS_CODES:
app.register_error_handler(code, handle_error)
答案 1 :(得分:10)
这与Flask 0.12兼容,是解决问题的一个非常好的解决方案(它允许以JSON或任何其他格式呈现错误)
from functools import wraps
from flask import Flask, redirect, jsonify
app = Flask(__name__)
def get_http_exception_handler(app):
"""Overrides the default http exception handler to return JSON."""
handle_http_exception = app.handle_http_exception
@wraps(handle_http_exception)
def ret_val(exception):
exc = handle_http_exception(exception)
return jsonify({'code':exc.code, 'message':exc.description}), exc.code
return ret_val
# Override the HTTP exception handler.
app.handle_http_exception = get_http_exception_handler(app)
https://github.com/pallets/flask/issues/671#issuecomment-12746738
答案 2 :(得分:6)
远非优雅,但以下工作将HTTPException
的所有子类绑定到单个错误处理程序:
from flask import jsonify
from werkzeug.exceptions import HTTPException
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error='error', code=code)
for cls in HTTPException.__subclasses__():
app.register_error_handler(cls, handle_error)
答案 3 :(得分:1)
在Flask> = 0.12中实现此目的的更干净的方法是为每个Werkzeug异常显式注册处理程序:
from flask import jsonify
from werkzeug.exceptions import HTTPException, default_exceptions
app = Flask('test')
def handle_error(error):
code = 500
if isinstance(error, HTTPException):
code = error.code
return jsonify(error='error', code=code)
for exc in default_exceptions:
app.register_error_handler(exc, handle_error)
答案 4 :(得分:0)
如果例外情况不起作用,您可以尝试 app.register_error_handler (或以非装饰方式使用 app.errorhandler )
答案 5 :(得分:0)
基于 Plain (non-HTML) error pages in REST api
我想返回json而不更改任何代码,所以我只在代码顶部添加了以下内容
@app.errorhandler(500)
def error_500(exception):
return jsonify({"error": str(exception)}), 500, {'Content-Type': 'application/json'}
@app.errorhandler(400)
def error_400(exception):
return jsonify({"error": str(exception)}), 400, {'Content-Type': 'application/json'}