【问题标题】:how to not have the flask server break when an error occurs? [closed]发生错误时如何不让烧瓶服务器中断? [关闭]
【发布时间】:2020-01-17 11:00:14
【问题描述】:

我使用烧瓶制作了一个 API 应用程序,它接受一个数字(十进制)作为输入并返回一些字符串。如果我发送一个字符串,这个应用程序会中断,并且在重新启动后可以正常工作。我不想每次在处理过程中发生一些错误时都重新启动。我该怎么做呢?

这是我的代码:

from flask import Flask, request, jsonify

# initiating the app
flask_api_app = Flask(__name__)


# the app accepts requests via "GET" and "POST" methods
@flask_api_app.route("/", methods=["GET", "POST"])
def output_risk_and_report():
    # getting json data from api call
    json_data = request.get_json(force=True)

    # now the processing part
    if json_data['number'] < 2:
        return jsonify(["the number is less than two"])
    else:
        return jsonify(["the number is not less than two"])


# main function, in which app will be run
if __name__ == "__main__":
    # running the app on local host
    flask_api_app.run(debug=True, host='127.0.0.1', port='8080')

不会破坏应用程序的调用示例:{"number":4}
中断应用程序的调用示例:{"number":"adfa"}

我要对代码进行哪些更改才能完成此操作?

编辑 1: 我很天真地在我的问题中举了这个例子。在我的原始程序中,将数据插入数据库时​​可能会出错,或者可能会在某些算术计算或其他方面出错。那么,有没有办法告诉flask继续为新的api请求提供服务,而不是在一个api调用发生错误时中断。

【问题讨论】:

  • 您可以控制变量的类型并引发异常。你试过吗?
  • 对不起。我很天真地在我的问题中举了这个例子。在我原来的程序中,将数据插入数据库时​​可能会出错,或者在某些算术计算或其他方面可能会出错。
  • 那么,有没有办法告诉flask继续为新的api请求提供服务,并且在仅一个api调用发生错误时不会中断。
  • 定义“中断”...?!
  • 好的。我的应用停止处理请求,但继续运行。

标签: python python-3.x flask


【解决方案1】:

如果用户提交的内容不能表示为整数,则需要触发返回并显示错误消息。

以下内容适用于3'3' 之类的提交

    # now the processing part
    try:
        number = int(json_data['number'])
    except ValueError:
        return jsonify(['Invalid submission'])

    # Number is now type integer

    if number < 2:
        return jsonify(["the number is less than two"])
    else:
        return jsonify(["the number is not less than two"])

【讨论】:

  • 这通常没有帮助。您实际上是在说应用程序需要完美,并且必须预测和处理所有错误,否则您的服务器将“崩溃”。在现实世界中并不是所有有用的解决方案......
【解决方案2】:

您可以制作一个作为全局异常处理程序的装饰器:

import traceback
from flask import current_app

def set_global_exception_handler(app):
    @app.errorhandler(Exception)
    def unhandled_exception(e):
        response = dict()
        error_message = traceback.format_exc()
        app.logger.error("Caught Exception: {}".format(error_message)) #or whatever logger you use
        response["errorMessage"] = error_message
        return response, 500

无论您在哪里创建应用实例,都需要这样做:

from xxx.xxx.decorators import set_global_exception_handler
app = Flask(__name__)
set_global_exception_handler(app)

这将处理您的应用程序中生成的所有异常以及您需要做的任何其他事情来处理它们。希望这会有所帮助。

【讨论】:

    【解决方案3】:

    查看文档时,我们会发现这种行为:

    handle_exception(e)

    处理没有与之关联的错误处理程序或从错误处理程序引发的异常。 这总是会导致 500 InternalServerError。

    始终发送 got_request_exception 信号。

    如果propagate_exceptions 为True,例如在调试模式下,错误将 重新引发,以便调试器可以显示它。否则,该 记录原始异常,并返回 InternalServerError。

    如果为 InternalServerError 或 500 注册了错误处理程序,它 将会被使用。为了保持一致性,处理程序将始终收到 内部服务器错误。原始的未处理异常可用作 e.original_exception。

    捕获此错误并对其进行处理的方法可能是这样的:

    @app.errorhandler(Exception)
    def handle_exception(e):
        # pass through HTTP errors
        if isinstance(e, HTTPException):
            return e
    
        # now you're handling non-HTTP exceptions only
        return render_template("500_generic.html", e=e), 500
    

    如果需要,您可以在此处找到源代码和额外文档:

    Flask pallets projects

    【讨论】:

      【解决方案4】:

      您的问题是由于您的程序在调试模式下运行引起的。 对于 linux,有一个名为 gunicorn 的工具。你应该设置 gunicorn 并且每次它崩溃时它都会再次运行你的烧瓶应用程序,所以你不需要自己重新启动。 不知道有没有windows的工具。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-06
        • 2021-01-21
        • 1970-01-01
        • 2016-11-29
        • 2019-05-19
        • 1970-01-01
        • 2019-04-01
        • 2020-10-19
        相关资源
        最近更新 更多