Re: Hard Flask Crash
- From:
- Jonathan Zempel
- Date:
- 2011-06-27 @ 15:27
I'm following-up on this post with a more accurate baseline and test harness
for reproducing the issue. The basic environment is:
Werkzeug==0.6.2
Jinja2==2.5.5
Flask==0.6.1
Flask-Babel==0.6
Flask-Script==0.3.1
These are the combined elements that contribute to an exception:
1) HTTP POST
2) Use lazy_gettext to add a "flash" message
3) HTTP redirect (302) to a render_template path
4) Loop through "get_flashed_messages" to display flash messages in the
template
At this point, there is a "maximum recursion depth exceeded" runtime
exception coming out of speaklater (used by Babel).
5) If Flask-Script is used to "runserver", then the dev server (on port
5000) will crash hard without the ability to catch the exception.
The test code and HTML template are pasted below. Right now, the workaround
for me is to change from lazy_gettext to gettext. But I'd appreciate any
feedback or best practice for improving the pattern here.
Thanks again,
Jonathan.
~~~~~
test.py
~~~~~
from flask import _request_ctx_stack, flash, Flask, redirect, \
render_template, request, url_for
from flaskext.babel import Babel, gettext, lazy_gettext
#from flaskext.script import Manager
from traceback import format_exc
app = Flask(__name__)
app.config["SECRET_KEY"] = "secret"
Babel(app)
@app.route("/", methods=["GET"])
def get():
try:
# Lazy gettext on HTTP GET works fine.
message = lazy_gettext("Hello World!")
flash(message)
return render_template("test.html")
except Exception:
return format_exc()
@app.route("/", methods=["POST"])
def post():
# Exception goes away if the following is gettext.
message = lazy_gettext("Goodbye World.")
flash(message)
url = url_for("get")
return redirect(url)
#manager = Manager(app)
if __name__ == "__main__":
app.run()
#manager.run() # <- Use this to crash the running server.
~~~~~~~~~~~~~~
templates/test.html
~~~~~~~~~~~~~~
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
{% for category, message in get_flashed_messages(with_categories=true)
%}
<div>{{ message }}</div>
{% endfor %}
<form action="{{ url_for("post") }}" method="post">
<input type="submit" />
</form>
</body>
</html>
On Sun, Jun 26, 2011 at 10:16 PM, Jonathan Zempel <jzempel@gmail.com> wrote:
> I've got a scenario where I'm reproducing a severe Flask crash. The
> elements include:
>
> Flask-Babel lazy_gettext + Flask flash get_flashed_messages + ???
> (Flask-Script "runserver" maybe?) == un-reported, un-catchable crash.
>
> Actually, anything that dereferences a session that contains lazy_gettext
> messages will crash hard. I've spent several days in and out of this
> problem. I still haven't exactly isolated the cause, and will continue to
> work on that. In the mean time, does this sound familiar to anyone? If I
> use Flask-Babel "gettext" for the flash messages, the crash goes away.
> Also, am I violating any kind of best practice for lazy translating flash
> messages?
>
> My current environment:
>
> Werkzeug==0.7dev
> Jinja2==2.6dev
> Flask==0.6.1
> Flask-Babel==0.6
>
> Although I've reproduced with the werkzueg+jinja versions required by Flask
> 0.6.1.
>
> Thanks,
> Jonathan.
>