Not sure if there's a better way to do this but I have a sign up page on my site and after a user signs up I add their initial data(stuff in the __init__ data model) then I start adding some other info in the same section which is giving me a broken pipe error. Oddly the code seems to work since the entries I'm expecting are in the database. I have tried moving around the .flush() command to see if it helps but it doesn't seem to be.
Traceback (most recent call last):
File "/Users/me/Dropbox/code/eclipseWorkSpace/website/pyramidwiki/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/channel.py", line 134, in handle_write
flush()
File "/Users/me/Dropbox/code/eclipseWorkSpace/website/pyramidwiki/lib/python2.7/site-packages/waitress-0.8.1-py2.7.egg/waitress/channel.py", line 249, in _flush_some
num_sent = self.send(chunk)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/asyncore.py", line 365, in send
result = self.socket.send(data)
error: [Errno 32] Broken pipe
Here's my code:
if 'form.submitted' in request.params:
firstname = request.params['firstname']
lastname = request.params['lastname']
email = request.params['email']
password = request.params['password']
try:
new_user = Users(email, firstname, lastname, password)
DBSession.add(new_user)
#DBSession.flush() #commit so we get error if any
#add some other info
user_data = DBSession.query(Users).filter(Users.email==email).first()
user_data.join_date = datetime.datetime.now()
#create random number for verification url
user_data.vertified = id_generator(50)
DBSession.flush() #doesn't seem to make a difference where the flush is
return HTTPFound(location = request.route_url('new'))
Any ideas?
This may not answer you question directly, but "you're doing it all wrong"(tm) :)
You don't need to re-query User object after you added it to the session - what's more, trying to query it from the database without doing session.flush() first will result in an error because there's no record in the database yet. I'd do something like this:
if 'form.submitted' in request.params:
firstname = request.params['firstname']
lastname = request.params['lastname']
email = request.params['email']
password = request.params['password']
try:
new_user = Users(email, firstname, lastname, password)
new_user.join_date = datetime.datetime.now()
new_user.verified = id_generator(50)
DBSession.add(new_user)
DBSession.flush() # should fail if user email is in the database
return HTTPFound(location = request.route_url('new'))
Also, you need to check that all branches of execution (i.e. the except: clause, the else: clause of "if 'form.submitted' in request.params" return something meaningful - you may be getting the exception because your view function returns None in some conditions. Actually, that's probably what was happening - the "user_data = DBSession.query(Users)" line was raising an exception, and the except: part was not returning anything
I too struggled with the same problem on my Pyramid project and contrary to comments on github, it wasn't with waitress.
In my case, the problem of Error: Broken Pipe only occured whenever I used redirects (HTTPFound, HTTPMovedPermanently etc.). Since your function also uses HTTPFound, I think the problem is the same.
Atleast for me, this error was due to pyramid_debugtoolbar extension. The reason is probably that whenever our view does soemthing like
return HTTPFound(foo)
it sends out a 302 in the header and a Connection:Close. The pyramid_debugtoolbar extension adds a lengthy body to the response. The client on seeing the header, closes the connection and does not accept the lengthy debug body. Hence the Broken Pipe message (Atleast that is what Wireshark shows).
Try disabling the pyramid_debugtoolbar in your app's .ini, it might help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With