我使用的是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')