I often have more luck the second time I ask a question... let's see 
if this rule holds.

I'm struggling with checking and reporting errors in forms that 
create or modify properties of PD classes in a ZPatterns application.

Automatic checks using Zope's built-in constraints or something like 
ValueHandler won't cut it, because they can't cover all the required 
rules - for example, checking if a Product SKU is being set to an 
existing SKU, or that a Customer is trying to use an email address 
already in use (and also because I want to return the form page with 
the errors indicated, rather than a generic error page). So I need a 
specific verification method for each class. This method will be used 
both when an object is edited and when its created. To use the method 
when creating an object, I either have to place it in the Specialist 
- which is bad, because the PD class should provide its validation 
code, or call it at commit time, using a SkinScript WHEN OBJECT 
CREATED,CHANGED clause. But verification methods called at commit 
time do their checks on the object properties, not on any submitted 
form field values. So they can test that a password is reasonably 
secure, but can't check that passwords typed in two form fields are 

One thing I can do is define a editInstance method which would verify 
the values in REQUEST.form and then call manage_changeProperties, or 
store a list of errors in the REQUEST and raise a 'FormError' 
exception. But I can't let this exception propagate freely, I have to 
catch it so I can display an appropriate error page. Also, if a form 
results in the creation of more than one object, I want to display 
all the errors that result from the creation of all the objects, but 
if the first object raises an exception, I can't create the second 
one (especially if the second one expects to get the id of the first).

Or I could forget about exceptions and simply return an error list 
from editInstance. Then it would be up to the method calling 
editInstance to raise an exception to roll back the created objects.

This is the only workable solution I got at the moment... I can get 
it to work, but I've chased solutions in the past that seemed good 
but ended up crashing... so I'd really appreciate any comments on 
possible flaws or problems I'm not seeing, or any other, better 

This is what it would look like (just an example, not showing cases 
where more complex stuff happens, like 2 objects being created with a 
single form):

In Customer (DataSkin PD class):

     def editInstance(self, REQUEST, errors):
         err = self.verify(REQUEST)
         if err != {}:

     def editInstance_html(self, REQUEST, RESPONSE):
         """Action method for editInstanceForm_html"""
         errors = {}
         self.editInstance(REQUEST, errors)
         if errors != {}:
             html = self.editInstanceForm_html(self, REQUEST, errors=errors)
             raise 'FormError', html

     def verify(self, REQUEST):
         errors = {}
         if REQUEST['name'] == '':
             errors['name'] = 'Please provide a name'
         return errors

In CustomerManager (Specialist):

     addCustomer(self, REQUEST, errors):
         ni = self.defaultRack.newItem()
         ni.editInstance(REQUEST, errors)
         return ni

     addCustomer_html(self, REQUEST, RESPONSE):
         """Action method for addCustomerForm_html"""
         errors = {}
         ni = self.addCustomer(REQUEST, errors)
         if errors != {}:
             html = self.addCustomerForm_html(self, REQUEST, errors=errors)
             raise 'FormError', html

And, of course, I can also have WHEN OBJECT ADDED,CHANGED CALL 
self.ensure_valid(), to catch anything that might get by the above 
checks. ensure_valid will raise its own error page, independent of 
the above.

TIA for any help/comments

Itai Tavor                      -- "Je sautille, donc je suis."    --
[EMAIL PROTECTED]            --               - Kermit the Frog --
-- 'Supposing a tree fell down, Pooh, when we were underneath it?' --
-- 'Supposing it didn't,' said Pooh after careful thought.         --

Zope-Dev maillist  -  [EMAIL PROTECTED]
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope )

Reply via email to