Python 任何异常的全局错误处理程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29332056/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Global error handler for any exception
提问by joscarsson
Is there a way to add a global catch-all error handler in which I can change the response to a generic JSON response?
有没有办法添加全局捕获所有错误处理程序,我可以在其中将响应更改为通用 JSON 响应?
I can't use the got_request_exception
signal, as it is not allowed to modify the response (http://flask.pocoo.org/docs/0.10/signals/).
我不能使用got_request_exception
信号,因为它不允许修改响应(http://flask.pocoo.org/docs/0.10/signals/)。
In contrast all signal handlers are executed in undefined order and do not modify any data.
相反,所有信号处理程序都以未定义的顺序执行并且不修改任何数据。
I would prefer to not wrap the app.handle_exception
function as that feels like internal API. I guess I'm after something like:
我宁愿不包装app.handle_exception
函数,因为这感觉像是内部 API。我想我在追求类似的东西:
@app.errorhandler()
def handle_global_error(e):
return "Global error"
Note the errorhandler
does not take any parameters, meaning it would catch all exceptions/status codes which does not have a specific error handler attached to them. I know I can use errorhandler(500)
or errorhandler(Exception)
to catch exceptions, but if I do abort(409)
for example, it will still return a HTML response.
请注意,errorhandler
它不接受任何参数,这意味着它将捕获所有没有附加特定错误处理程序的异常/状态代码。我知道我可以使用errorhandler(500)
或errorhandler(Exception)
捕获异常,但如果我这样做abort(409)
,它仍然会返回一个 HTML 响应。
采纳答案by ThiefMaster
You can use @app.errorhandler(Exception)
:
您可以使用@app.errorhandler(Exception)
:
Demo (the HTTPException check ensures that the status code is preserved):
演示(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)
Output:
输出:
$ 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"
}
If you also want to override the default HTML exceptions from Flask (so that they also return JSON), add the following before app.run
:
如果您还想覆盖来自 Flask 的默认 HTML 异常(以便它们也返回 JSON),请在之前添加以下内容app.run
:
from werkzeug.exceptions import default_exceptions
for ex in default_exceptions:
app.register_error_handler(ex, handle_error)
For older Flask versions (<=0.10.1, i.e. any non-git/master version at the moment), add the following code to your application to register the HTTP errors explicitly:
对于较旧的 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)
回答by bwind
Far from elegant, but the following works for tying all subclasses of HTTPException
to a single error handler:
远非优雅,但以下适用于将所有子类绑定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)
回答by lol
This is Flask 0.12 compatible, and a very good solution to the problem (it allows one to render errors in JSON or any other format)
这是 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
https://github.com/pallets/flask/issues/671#issuecomment-12746738
回答by Suresh Ganta
If the Exceptions doesn't work, you may try app.register_error_handler
(or use app.errorhandler
in a non-decorator way)
如果异常不起作用,您可以尝试app.register_error_handler
(或app.errorhandler
以非装饰器方式使用)
回答by nfvs
A cleaner way to implement this in Flask >=0.12 would be to explicitly register the handler for every Werkzeug exception:
在 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)
回答by julianalimin
Based on Plain (non-HTML) error pages in REST api
I wanted to return json without changing any of my code at all, so I just added the following on the top of my code
我想在不更改任何代码的情况下返回 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'}