[Zope-dev] Stumped about handling this particular exception...

Amos Latteier amos@aracnet.com
Tue, 27 Apr 1999 23:13:00 -0700


At 10:19 PM 4/27/99 -0400, Skip Montanaro wrote:
>
>I asked this question in a different form before but got only silence from
>the list.  I'll give it another try...

I'm sure you're aware of the high volume of the Zope lists. It's more like
a tidal wave of other questions rather than silence ;-)

>I'm using ZServer and a snapshot of the Zope CVS directory.  When a user of
>the web site fails to input a required form element, ZServer spits out
>
>    Server Error: exceptions.ValueError, No input for required field<p>:
>    file: /home/dolphin/skip/src/Zope/lib/python/ZPublisher/Converters.py
line: 114
>
>on the controlling terminal and the user sees
>
>    Error response
>
>    Error code 500. 
>
>    Message: Internal Server Error. 
>
>instead of a useful message that will help the user figure out what they did
>wrong.  This makes them think my web site is broken, when it's actually
>their input that's broken...

Yes. ZPublisher's type converters are quite primitive. They don't offer
much control over how value are coerced and frustratingly they don't allow
control over how errors are handled. Finally, there is no interface for
extending the converters, i.e. it's hard to figure out how to add your own
converters.

It may be that ZPublisher doesn't have much business validating form input.
When I complain to Jim Fulton that the converters are pretty lame he
usually tells me that they are not for form validation, but for argument
marshalling.

Improving the ZPublisher converters is a worthwhile problem, IMO. In
addition, making ZPublisher's error reporting more flexible is also a
worthwhile project.

In the short term I can recommend these avenues to solve your problem.

  * Don't use type converters and do all the form validation in your
published object. This way you have total control. In fact you can continue
to use the type converters if you wish, a la.

  import ZPublisher.Converters

  def published_method(spam,eggs):
    "Convert spam and eggs myself"
    try: spam=Zpublisher.Converters.field2tokens(spam)
    except: warn_user()   
    ...

  * Write your own type converters which do not raise exceptions. Here's an
example which would be relevant in your case.

  import ZPublisher.Converters
  def my_required(v):
    "A converter which overrides the standard required converter"
    try: return ZPublisher.Converters.field2required(v)
    except: return None
  ZPublisher.Converters.type_converters['required']=my_required

  * Subclass HTTPResponse and change the error handling. HTTPResponse now
has a _error_html method which can be overridden to provide some control
over errors. This option is probably the most work but there are some
interesting possibilities here.

For example, maybe ZPublisher could be extended by some protocol which
allows it to fall back to publishing certain objects/methods when an error
is raised trying to publish a given object. Of course, this needs much more
thought. Maybe this should be done on the object level, rather than the
ZPublisher level. For example, Zope's DTML Documents and Methods call the
(acquired) 'standard_error_message' object if an exception is raised while
rendering...

I'd be happy to hear opinions about how to improve type converters and/or
error handling.

Hope this helps.

-Amos