Templates 如何呈现Flask中的错误页面,而不导致请求蓝图中的错误循环?

Templates 如何呈现Flask中的错误页面,而不导致请求蓝图中的错误循环?,templates,flask,error-handling,Templates,Flask,Error Handling,我有一个问题,我的Flask错误处理过程在发生错误的蓝图上下文中呈现模板。 我需要一个更好的架构或如何正确忽略问题的建议 my flask应用程序的简化布局如下: app/ 错误/ 模板/ 错误/ 500.html 1.py 销售/ 模板/ __初始值 在salse/\uuuuu init\uuuuuuuu.py中有@bp.contex\u处理器,用于注入购物车对象,使其可用于所有销售/模板/(与典型的当前用户类似): salse/\uuuuu init\uuuuuu.py @上下文处理器 d

我有一个问题,我的Flask错误处理过程在发生错误的蓝图上下文中呈现模板。 我需要一个更好的架构或如何正确忽略问题的建议

my flask应用程序的简化布局如下:

app/
错误/
模板/
错误/
500.html
1.py
销售/
模板/
__初始值
salse/\uuuuu init\uuuuuuuu.py
中有
@bp.contex\u处理器
,用于注入
购物车
对象,使其可用于所有
销售/模板/
(与典型的
当前用户
类似):

salse/\uuuuu init\uuuuuu.py
@上下文处理器
def inject_cart():
返回目录(购物车=客户端请求('https://1.1.1.1/cart/load))
handler.py
@bp.应用程序错误处理程序(500)
def内部_错误(错误):
返回渲染模板('500.html'),500
购物车是从外部系统加载的

问题在于与外部系统的连接错误处理

期望情景
  • 用户长时间未工作-外部系统已关闭连接
  • 用户正在单击某个内容
  • 在外部系统连接包中,存在异常“用户授权已过期”
  • Flask捕获错误并呈现
    errors/500.html
    ,要求用户再次登录(并在后台对外部系统进行授权)
  • 当前情景
  • 如上
  • 如上
  • 如上
  • Flask捕获错误并正在调用
    render\u模板(errors/500.html)
  • render_模板('errors/500.html')
    中,
    flask.app.flask\35; update_模板_context()
    检查请求蓝图(
    reqctx.request.blueprint
    )是否为
    销售
    ,最后执行
    inject\u cart()
  • injection\u cart():
    正在尝试请求外部系统,但连接已关闭,因此错误来自3。再次发生
  • 最后,Flask显示了它的内置“服务器错误”页面
  • 我认为这是不好的,错误处理没有从蓝图中分离出来,在蓝图中错误发生导致错误泛滥

    但是您是否有一个更好的应用程序结构的建议来忽略这个问题?或者我不应该使用
    render\u template()
    来处理错误模板


    目前,我只是使用了
    重定向()
    而不是
    渲染模板()
    。但是我觉得有一个更好的解决方案。

    假设您的Flask应用程序是在
    app/\uu init\uuuuuuuuuupy
    中定义的,我认为您的模板结构应该是

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
            __init__.py
    
    除非您在应用程序/蓝图初始化时指定模板文件夹。请参阅
    帮助(flask.flask)

    编辑:增加清晰度

    您可以覆盖应用程序主模板目录中的模块模板。你不能在模块中覆盖你的应用程序的主模板(如果不利用一些底层的jinja操作的话)。因此,如果您的结构是这样的:

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                errors/
                    500.html
            __init__.py
    
    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    
    销售蓝图
    app\u errorhandler
    将覆盖您的应用
    errorhandler
    ,但尝试呈现
    errors/500.html
    将呈现
    app/templates/errors/500.html
    。我相信这是为了允许覆盖第三方模块模板而设计的

    最好的约定是将模块模板嵌套在模块名称中,如以下结构:

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                errors/
                    500.html
            __init__.py
    
    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    
    然后,您的销售蓝图可以处理自己的500个错误,就像这样

    @bp.app_errorhandler(500)
    def internal_error(error):
        return render_template('sales/errors/500.html'), 500
    
    然后,如果您确实想要或需要,您可以覆盖销售模块错误模板

    app/
        templates/
            sales/
                errors/
                    500.html
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    

    假设您的Flask应用程序是在
    app/\uuuuu init\uuuuuupy
    中定义的,我认为您的模板结构应该是

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
            __init__.py
    
    除非您在应用程序/蓝图初始化时指定模板文件夹。请参阅
    帮助(flask.flask)

    编辑:增加清晰度

    您可以覆盖应用程序主模板目录中的模块模板。你不能在模块中覆盖你的应用程序的主模板(如果不利用一些底层的jinja操作的话)。因此,如果您的结构是这样的:

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                errors/
                    500.html
            __init__.py
    
    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    
    销售蓝图
    app\u errorhandler
    将覆盖您的应用
    errorhandler
    ,但尝试呈现
    errors/500.html
    将呈现
    app/templates/errors/500.html
    。我相信这是为了允许覆盖第三方模块模板而设计的

    最好的约定是将模块模板嵌套在模块名称中,如以下结构:

    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                errors/
                    500.html
            __init__.py
    
    app/
        templates/
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    
    然后,您的销售蓝图可以处理自己的500个错误,就像这样

    @bp.app_errorhandler(500)
    def internal_error(error):
        return render_template('sales/errors/500.html'), 500
    
    然后,如果您确实想要或需要,您可以覆盖销售模块错误模板

    app/
        templates/
            sales/
                errors/
                    500.html
            errors/
                500.html
        handlers.py
    
        sales/
            templates/
                sales/
                    errors/
                        500.html
            __init__.py
    

    我将模板移动到blueprint:bp=blueprint('sales',name,template_folder='templates'),但模板在哪里并不重要,问题与我提到的相同。如果您希望覆盖
    sales
    蓝图的
    errors/500.html
    模板,模板应位于
    sales/templates/errors/500.html
    。然后,您应该使用
    return render_template('errors/500.html')、500
    进行渲染。我的问题不是为销售模块设置专用的
    500.html
    错误页面,而是为整个应用程序设置一个
    500.html
    错误页面。问题是,如果销售模块
    \uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuupy
    中存在异常,则呈现全局错误/500.html会导致在请求时再次调用sales/\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu init.py。这使得错误雪崩。我会尝试使用
    @app.errorhandler
    ,而不是让蓝图来处理它。这可能会避免您的
    上下文\u处理器
    。您还可以在
    注入车中检测到500。最后,你可以做你的ses