On Nov 15, 2005, at 5:34 PM, Ian Bicking wrote:
I do have a question for you: how are you going to handle
Exceptions and the ability to display nice errors with `flash`?
Typically, I end up with a try:except:finally block where I `flash
('some nice error message')` and do a `hub.rollback()`. I may
have a different error message for different types of Exceptions...
I think "expected" exceptions (including redirects) should not roll
back the transaction. Unexcepted exceptions (everything else
should). However, you should be able to explicitly roll back or
commit the transaction if the decorator doesn't do what you want.
Agreed, especially when it comes to redirects. This is actually one
reason that I don't like redirect being an Exception... I would
prefer it to be a `return` instead... it causes all sorts of confusion.
But, I think you missed my point on how to set the error message to
be `flashed` in the case of an exceptional Exception ... I don't want
to have to continue to use a try:except: clause to handle error
messages in the context of an automatic request-per-transaction. I
would like this to be automated as well, since it probably needs to
happen inside of the transaction `try:except:` in the decorator.
From the wiki, I think your suggestion was:
hub.begin()
try:
do stuff
except:
hub.rollback()
raise
else:
hub.commit()
This still leaves me to catch the re-raised exception and display an
error message. Why not go ahead and handle the setting of the error
message?
hub.begin()
try:
do stuff
except Exception, e:
hub.rollback()
message = err_map.get(e.__class__, 'Generic message')
flash(message)
else:
hub.commit()
This would reduce a lot of boilerplate error handling. Most of my
controller methods look like this:
@turbogears.expose()
def update_frobble(self, frob_id, new_name):
hub.begin()
try:
frobbler = Frobbler.get(frob_id)
frobbler.set(name=new_name)
except SQLObjectNotFound:
flash("Couldn't find frobbler!')
hub.rollback()
else:
hub.commit()
raise cherrypy.Redirect('/some/page')
It would be great if all I had to write was:
@turbogears.expose(err_map={SQLObjectNotFound :
"Couldn't find frobbler!"})
def update_frobble(self, frob_id, new_name):
frobbler = Frobbler.get(frob_id)
frobbler.set(name=new_name)
raise cherrypy.Redirect('/some/page')
So in your example you'd have to explicitly roll back the
transaction if you didn't want your otherwise normal-looking
response to cause a rollback.
I almost always want Exceptions to trigger a rollback, but I also
frequently want to display an error message using `flash` that
describes to the user what happened.
Does this make sense, or am I alone here?
-- Jon