我在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,并且该函数在某些输入下崩溃。当然,这不应该发生。但是,这样做的话,用户的体验会很糟糕。
详细信息:
flask.session
中,即作为cookie 关键是语句flask.session.pop
从session
存储中删除了表单数据,但是当函数崩溃时,相应的cookie仍保留在用户的浏览器中。每次重新加载都会再次触发该错误。重新启动浏览器可能会有所帮助(取决于session.permanent
标志)。唯一可以保证的解决方法是从浏览器中手动删除cookie。这实际上使网页无法使用。
我认为我可以通过设置非常短的cookie寿命(大约15秒)或在每次重新启动后生成新的密钥来缓解该问题。我没有尝试过,如果会话cookie包含其他数据,绝对不是一个好的解决方案。
如何使上述功能更强大?
答案 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