Flask发布/重定向/获取模式无法从错误中恢复

时间:2019-04-27 15:44:03

标签: python flask

我在Flask视图函数中有一个错误恢复问题。它的简化版本在这里:

@app.route('/log', methods=['POST', 'GET'])
def elog():
    form = LogForm()
    if form.validate_on_submit():
        flask.session['logformdata'] = form.data
        return flask.redirect(flask.url_for('elog'))

    try:
        formdata = flask.session.pop('logformdata')
    except KeyError:
        return flask.render_template('log.html', form=form)

    log = ... # result of a query
    form.process(data=formdata)
    return flask.render_template('log.html', form=form, log=log)

重要的部分是它实现了post / redirect / get模式,并将POST和GET之间的表单数据存储在通过HTTP cookie实现的flask.session存储中。

现在让我们假设某个地方有一个bug,并且该函数在某些输入下崩溃。当然,这不应该发生。但是,这样做的话,用户的体验会很糟糕。

详细信息:

  • 用户发布表单(POST)
  • 表单数据存储在flask.session中,即作为cookie
  • 重定向后,再次调用该函数(GET),但现在它意外崩溃。用户看到一些错误消息。那不好,但是会发生错误。
  • 用户重新加载了打算重新开始的页面,但一次又一次地收到相同的错误!

关键是语句flask.session.popsession存储中删除了表单数据,但是当函数崩溃时,相应的cookie仍保留在用户的浏览器中。每次重新加载都会再次触发该错误。重新启动浏览器可能会有所帮助(取决于session.permanent标志)。唯一可以保证的解决方法是从浏览器中手动删除cookie。这实际上使网页无法使用。

我认为我可以通过设置非常短的cookie寿命(大约15秒)或在每次重新启动后生成新的密钥来缓解该问题。我没有尝试过,如果会话cookie包含其他数据,绝对不是一个好的解决方案。

如何使上述功能更强大?

3 个答案:

答案 0 :(得分:0)

我认为您的简化示例忽略了表示崩溃的重要部分。

如果某些逻辑意外崩溃,则应该期望它能够处理这些情况。例如,将其包装在通常的try/catch中,然后在catch块中删除会话cookie。

答案 1 :(得分:0)

您正在手动管理会话,这是导致此问题的原因。请考虑在您的应用程序中实现Message Flashing。您可以自定义闪烁以使用服务器端会话,甚至使用cookie。甚至可以通过重定向在多个页面上维护Flash消息。

答案 2 :(得分:0)

如果无法处理视图本身中的错误,我的方法是针对整个应用register an error handler,并在此处管理会话,即重置为默认/安全状态。

示例:

@app.errorhandler(500)
def handle_internal_server_error(ex):
    """Handle an unexpected and uncaught (500) server error."""

    # Reset session here & display error (e.g. flash or other)

    return  # redirect or render