Python Flask-蓝图错误处理



我使用的是flask,我有我的功能包,并使用蓝图,这很好,但我希望有一个全局404和错误页面,它位于任何特定功能包之外。

当我触发一个404烧瓶时,仍然使用默认的404处理程序来处理这个问题,并且我没有得到我的自定义模板。以下是我的代码:

init.py

# Define the WSGI application object
app = Flask(__name__)
# Load Configuration
app.config.from_object('config')
from .user.route import mod_user as user_module
from .route.error_handler import mod_error as error_module
# Register blueprints
app.register_blueprint(user_module)
app.register_blueprint(error_module)

error_handler.py

import traceback
from flask import Flask, render_template, Blueprint
mod_error = Blueprint('error', __name__, template_folder='templates')

@mod_error.errorhandler(404)
def not_found(e):
print(e)
return render_template('404.html')

@mod_error.errorhandler(Exception)
def general_error(e):
print(e)
print(traceback.format_exc())
return render_template('error.html')

我的功能路线在project.user.route.py中定义

全局路由\错误处理程序在project.route.error_handler.py

全局错误模板在project.templates

我设法解决了这个问题,这很简单,当我从一个脚本中的所有内容转移到使用蓝图时,我创建了错误处理模块,我认为我需要在注释中使用模块名称:

@mod_error.errorhandler(404)

这是因为这是我在我的控制器中为我的用户功能做的:

@mod_user.route('/read', methods=['POST', 'GET'])

以下是我需要做的,即导入我的应用程序对象,然后将其用于错误处理函数:

import traceback
from flask import Flask, render_template, Blueprint
from .. import app
mod_error = Blueprint('error', __name__, template_folder='templates')

@app.errorhandler(404)
def not_found(e):
print(e)
return render_template('404.html')

@app.errorhandler(Exception)
def general_exception(e):
print(e)
print(traceback.format_exc())
return render_template('error.html')

这现在可以在全局级别处理我的任何功能包之外的所有错误,我想实现ControllerAdvice的效果,它可以处理Spring MVC中所有控制器的所有异常。

您实际上不必像@berimblo所说的那样导入app对象。是的,他确实有正确的想法,因为在烧瓶中,对于404和其他路由错误,文档说:

蓝图无法处理404路由错误,因为404发生在可以确定蓝图之前的路由级别。

因此,在蓝图上使用errorhandler()无法处理404错误。这对404个错误无效:

from flask import Flask, render_template, Blueprint
mod_error = Blueprint('error', __name__, template_folder='templates')
@mod_error.errorhandler(404)
def not_found(e):
...

相反,您必须将错误处理程序添加到应用程序对象上,就像@berimblo所做的那样:

@app.errorhandler(404)
def not_found(e):
print(e)
return render_template('404.html')

但是,这个的问题是,您正在增加更改,您将遇到循环导入问题(这类问题(。因为声明app对象的模块可能会导入声明blueprint对象的模块,所以与blueprint模块同时导入app模块以获取app对象。

解决方案:对blueprint对象使用app_errorhandler方法。文档字符串上写着:

类似于:meth:Flask.errorhandler,但用于蓝图。该处理程序用于所有请求,即使在蓝图之外也是如此。

这意味着您不必执行循环导入操作。相反,你可以写:

import traceback
from flask import Flask, render_template, Blueprint
mod_error = Blueprint('error', __name__, template_folder='templates')
@mod_error.app_errorhandler(404)
def not_found(e):
print(e)
return render_template('404.html')
@app.app_errorhandler(Exception)
def general_exception(e):
print(e)
print(traceback.format_exc())
return render_template('error.html')

最新更新