At 12:49 AM 1/6/01 +0000, Steve Alexander wrote:
WHEN OBJECT ADDED, CHANGED CALL self.ensure_conditions_hold()
I write the ensure_conditions_hold method so that it returns None if everything is ok, but raises an exception if there is a problem with the new state of the object.
That's all fine. However, I want to catch this exception in my application, and handle it in a friendly way. However, I've tried using dtml-try blocks and try: except: blocks from Python Scripts, and either way, I cannot catch the exception. It still causes Zope to return the standard_error_message screen.
I can only speculate that this is all due to the way that triggers get executed at the end of transaction. I guess I'll have to validate the data twice if I want to provide helpful feedback to the user.
How do I catch an error raised by a Trigger?
What Ty and I usually do is raise user-friendly error messages (in HTML) to begin with, so there's no need to trap them in an except block; Zope's normal handling works okay then. This is the "as designed/intended" solution to your overall problem. (We often use dtml-raise for this, as it makes it easier to create a full-screen HTML error page.) But to answer the question you asked, you can do it by performing a subtransaction commit, wrapped in a try or dtml-try block. This will fire the triggers in a context where you can trap the exception. We suggest you only use this trick when you really need it, however, and in your situation as described I don't think you really need it. Even if "ensure_conditions_hold" can't be changed to raise friendly exceptions, you can always put a wrapper routine around it that catches and re-raises them. The key idea here is that it's perfectly okay to let an exception propagate to the user, if formatted properly. You probably *want* it to happen, to ensure that *everything* gets rolled back. Even if you do the subtransaction trick and trap the error, you still want to make sure the transaction as a whole aborts, since SQL (for example) might already have been sent to a database.