Web Form Error Handling Techniques

Jp Calderone exarkun at intarweb.us
Fri Jan 16 14:29:59 EST 2004


On Fri, Jan 16, 2004 at 09:53:47AM -0800, Sean Abrahams wrote:
> The following is a reprint of a message I sent to the tutor list a long 
> time ago, that I haven't gotten around to discussing with anyone else 
> and failed to hear a reply on the tutor list. Hoping someone here may 
> want to have some dialog.
> 
> --
> 
> I'm learning to write unit tests and am trying to write them for a web
> application I'm working on.
> 
> I'm currently writing a test that is to purposefully fail by passing
> invalid data to a function. However this brought me to thinking about
> how to handle errors.
> 
> Let me set up a hypothetical scenario.
> 
> I have a web form with name and age as its two fields. When a person
> enters his/her information and submits the form, I take the two fields
> and create a dict that contains {'name' : 'Foo', 'age' : '82'}.
> 
> I pass this information to a function called, insertData which
> looks something like this:
> 
> def insertData(data):
> 
>     # test data for validity
>     if not data['name'].isalpha():
>        raise InvalidDataError(data['name'], "Name contains non-alpha
>        characters")
>     if not data['age'].isdigit():
>        raise InvalidDataError(data['age'], "Age contains non-digit
>        characters")
> 
>     sql = """
>     INSERT INTO people (name, age) VALUES ('%s', '%s')
>     """ % (data['name'], data['age'])
> 
>     executeSQL(sql)

  The last two statements are not ideal.  You probably want:

    sql = """
    INSERT INTO people (name, age) VALUES(%s, %s)
    """
    args = (data['name'], data['age'])

    executeSQL(sql, args)

  instead.  But that's not what you asked about..

> 
> I should first check to see if the data is valid, meaning that the
> name contains only alpha characters and the age only containing
> numeric characters.
> 
> If I raise an exception, how would one handle the reprinting of the
> web form with a red * next to the field that contains invalid data? If
> one field is in error, I can see that upon receiving an exception you
> can have your code just reprint the web form with the red star, but
> what about when both fields are in error, do you have the exception
> create a list which then your code checks to see if it exists and then
> loops through it to know what fields are in error?
> 
> And then again, perhaps I'm completely wrong and am going about this
> in an amateur manner.

  Consider this version of insertData:

    def insertData(data):
        errors = {}
        if not data['name'].isalpha():
            errors['name'] = InvalidDataError(data['name'], "...")
        if not data['age'].isdigit():
            errors['age'] = InvalidDataError(data['age'], "...")

        if errors:
            raise InvalidFormPostError(data, errors)
        
        # Your version, to minimize changes
        sql = """
        INSERT INTO people (name, age) VALUES ('%s', '%s')
        """ % (data['name'], data['age'])

        executeSQL(sql)

  Now full form validation can be attempted, and full information about
which fields are erroneous is available.  Those fields can be marked, and
the rest can be filled out with the values previously entered.

  Nevow might also be of interest to you.  It offloads much of the work of
form validation:

    http://stewstuff.com/doc/nevow.xhtml
    http://soundfarmer.com/content/logs/NevowLecture11-25-03.txt
    http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

  Jp




More information about the Python-list mailing list