代码之家  ›  专栏  ›  技术社区  ›  smaug

如何在Python中返回异常的JSON响应?

  •  1
  • smaug  · 技术社区  · 6 年前

    我不能用这个 got_request_exception 信号,因为不允许修改响应( http://flask.pocoo.org/docs/0.10/signals/

    相反,所有信号处理程序都是按未定义的顺序执行的,不修改任何数据。

    我不想把衣服包起来 app.handle_exception

     @app.errorhandler()
     def handle_global_error(e):
         return "Global error"
    

    注意 errorhandler 不接受任何参数,这意味着它将捕获所有未附加特定错误处理程序的异常/状态代码。我知道我可以用 errorhandler(500) errorhandler(Exception) 捕捉异常,但如果我 abort(409)

    0 回复  |  直到 8 年前
        1
  •  57
  •   FGreg ThiefMaster    7 年前

    你可以用 @app.errorhandler(Exception) :

    演示(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)
    

    对于较旧的烧瓶版本(<=0.10.1,即当前任何非git/主版本),将以下代码添加到应用程序中以显式注册HTTP错误:

    from werkzeug import HTTP_STATUS_CODES
    for code in HTTP_STATUS_CODES:
        app.register_error_handler(code, handle_error)
    
        2
  •  13
  •   lol    7 年前

    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

        3
  •  8
  •   bwind    7 年前

    远非优雅,但下面的工作,为捆绑所有子类的 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)
    
        4
  •  2
  •   Dirk    6 年前

    在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)
    
        5
  •  0
  •   julianalimin    5 年前

    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'}
    
        6
  •  0
  •   MarredCheese Lionia Vasilev    5 年前

    app.register_error_handler (或使用) app.errorhandler 以非装饰性的方式)

    https://github.com/pallets/flask/issues/1837