Python 烧瓶-当使用logging.handlers.HTTPHandler发布错误时,您可以重定向或刷新这些错误吗?

Python 烧瓶-当使用logging.handlers.HTTPHandler发布错误时,您可以重定向或刷新这些错误吗?,python,flask,Python,Flask,我有一个在整个系统中使用的记录器,它使用HTTP处理程序报告错误,然后flask捕获它们,我希望能够刷新它们,以便用户能够看到错误 我特意不使用flasks normal logger,因为它需要扩展到整个系统,以便正确记录错误 然而,尽管flask似乎可以捕获错误并从logs视图中打印出来,但它无法将错误闪存给用户或重定向到显示错误的页面 以下是我的处理程序/记录器设置的相关部分: 'error_handler': { 'class': 'logging.handlers.HTTPHa

我有一个在整个系统中使用的记录器,它使用HTTP处理程序报告错误,然后flask捕获它们,我希望能够刷新它们,以便用户能够看到错误

我特意不使用flasks normal logger,因为它需要扩展到整个系统,以便正确记录错误

然而,尽管flask似乎可以捕获错误并从logs视图中打印出来,但它无法将错误闪存给用户或重定向到显示错误的页面

以下是我的处理程序/记录器设置的相关部分:

'error_handler': {
    'class': 'logging.handlers.HTTPHandler',
    'formatter': 'debug_formatter',
    'level': 'WARNING',
    'filters': ['Web_filter'],
    'host': 'localhost:5000',
    'url' : '/logs',
    'method' : 'POST',
},
下面是捕获这些错误的视图:

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    message = str(request.form['message'])
    print("message: " + message) #this works
    flash(message) #this doesn't
    return render_template('500_unhandled.html', title='ERROR', e = message) #neither does this
更新:我实际上切换了创建记录器的方法,因此它稍微简单一些,但仍然不起作用:

 http_handler = HTTPHandler('localhost:5000','/logs',method='POST',)
 http_handler.addFilter(WebFilter())
 new_logger.addHandler(http_handler)
更新2:我尝试了只返回消息的建议,但这让我怀疑我在哪里可以访问此返回值,因此,如果您能提供更多帮助,我们将不胜感激。以下是该版本:

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    message = str(request.form['message'])
    print("message: " + message) #this works
    return message #this doesn't really do anything
我还尝试使用中止方法:

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    message = str(request.form['message'])
    print("message: " + message) #this works
    abort(500, message) #this doesn't work either
更新3: 我在view函数中添加了一条日志消息,只是想看看是否出于某种原因从阻止通信的其他位置或线程调用它。以下是两条不同的日志消息以及生成它们的代码:

@app.route('/', methods=['GET', 'POST'])
@app.route('/index', methods=['GET', 'POST'])
def index():
    logger.error('test error')

Prints: 
   routes:Thread-1:test error

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    message = str(request.form['message'])
    logger.info("where am i?")
    print("message: " + message) #this works
    abort(500, message)

Prints: 
routes:Thread-2:where am i?
message: test error
它们在不同线程中的事实是有问题的还是正常的

更新4:我刚才注意到的另一件奇怪的事情是,我无法从logs视图访问会话变量。这让我觉得,出于某种原因,日志与应用程序的其他部分是分开的

更新5:为了重申我在评论中提到的一些非常奇怪的事情,abort语句可以工作并重定向到我的错误处理程序,但是错误页面“500.html”在重定向到主页之前只在屏幕上闪烁。以下是我的错误处理程序的代码:

@app.errorhandler(500)
def handle_500(e):
    original = getattr(e, "original_exception", None)
    if original is None:
        # direct 500 error, such as abort(500)
        print(e)
        return render_template("500.html",e = e), 500
    # wrapped unhandled error
    return render_template("500_unhandled.html", e=original), 500

当您调用
logger.info()
时,它会向服务器发送带有消息的
POST
请求,并查看函数
logs()
处理此请求。它获取消息,打印它,闪烁它,并将页面返回到记录器请求。这样,消息就被打印出来了

当您在浏览器中访问此页面时,浏览器会向服务器发送无消息的
GET
请求,再次查看函数
logs()
处理此请求。它试图获取消息,但请求中没有消息。所以它既不会被打印也不会被闪现


要显示消息,您需要将它们存储在某个位置。当您收到
POST
请求时,将消息添加到数据库/数组/文件/etc。当您收到
get
请求时检索消息并刷新它们,等等。

请参阅下面的编辑以获得更好的答案

我不确定我是否清楚地理解了这个问题,但我会试一试

你的问题听起来像是HTML问题。闪烁要求您在返回的HTML模板中添加闪烁设置:您必须在返回的HTML中指定它必须显示您的闪烁消息:

HTML示例:

<h1>My HTML title</h1>
{% with messages = get_flashed_messages() %}
    {% if messages %}
        {% for message in messages %}
            <p>{{ message }}</p>
        {% endfor %}
    {% endif %}
{% endwith %}
此模板(在本例中,
包含_flash.html
)必须包含在项目目录中的/templates文件夹中才能正确访问,并且必须包含类似于上一个html代码的内容

最后,确保在函数中添加单独的部分来处理POST请求,而不仅仅是常规查看页面:

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    if request.method == "POST":
        message = str(request.form['message'])
        flash(message)
        # goes back to same page so user can view messages
        return redirect(url_for('logs')) 
    else:
        # perhaps flashes messages and has form to POST messages
        return render_template('contains_flash.html')
请记住,对于上述所有代码,用户必须到达
您的url/logs
才能访问您的日志(闪现消息)

最后,解释建议的返回语句:ie
returnmessage
。如果使用
返回消息
,则当用户转到“url/log”时,它将显示与该消息等价的HTML。因此,它将返回您的消息,但没有任何HTML格式

编辑:考虑更多问题的答案

由于
flash()。因此,闪烁显然不起作用。打印是有效的,因为您不会在web浏览器中(在不同的会话中)访问消息,而只是将消息打印到您可以看到它的终端上

相反,使用数据库存储记录的消息,然后将其显示给用户。一个相当容易设置的数据库是,您可以使用它

import sqlite3
# ... previous code

conn = sqlite3.connect('db.sqlite') # your db name
conn.row_factory = lambda cursor, row: row[0] # does not return tuple
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS errors
         (message TEXT NOT NULL)''') # create table
conn.commit() # saves database operations

@app.route('/logs' , methods = ["GET","POST"])
def logs():
    if request.method == "POST":
        message = str(request.form['message'])
        c.execute('INSERT INTO errors (message) VALUES (?)', (message,))
        conn.commit()

    # if not a POST, request must be from user:
    errors = c.execute('SELECT message FROM errors').fetchall() # get all messages: this can be changed
    return render_template('messages.html', errors=errors)
messages.html显示错误:

<h1>Errors below</h1>
{% for error in errors %}
    <p>{{ error }}</p>
{% endfor %} 
下面的
错误
{错误%中的错误为%0}
{{error}}

{%endfor%}

现在,以上内容应该是存储记录错误的简单方法。根据需要向表中添加更多字段。

这是因为HTTPHandler类是如何工作的。

它将向
/log
端点发出错误消息。日志端点将呈现的html和消息返回给记录器。但是记录者不能用它做任何事情。它不会将值返回到用户的浏览器。所以什么也没有出现

该类的相关行。它甚至提到它对结果无能为力。

h.getresponse()#对结果无能为力

您是否尝试过对
flash(message)
进行评论并仅使用
返回消息
?我尝试过,由于您的建议,请查看我的更新以了解更多详细信息。您是否使用了此功能?是的,我正在使用@fcsrCool回复感谢您的回复,然而,我认为这是不正确的。首先,当处理
POST
请求时,它不会闪烁或重定向,它只会打印这是我的帖子的关键。其次,我从未尝试通过浏览器访问日志视图,它只是用来处理传入的请求,而不是一个页面本身。为了证明这一点,我从中完全删除了
GET
方法,其功能是相同的。你怎么知道
POST
请求是透明的
<h1>Errors below</h1>
{% for error in errors %}
    <p>{{ error }}</p>
{% endfor %}