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

Reply via email to