Skip to content Skip to sidebar Skip to footer

Error Handling With Python + Pylons

What is the proper way to handle errors with Python + Pylons? Say a user sets a password via a form that, when passed to a model class via the controller, throws an error because i

Solution 1:

What are you using to validate your forms? I'm using formalchemy. It validates the input data using built-in and custom validators, and feeds a list with the errors it finds. You can then display that list in any way you want in your template.

Documentation here.

Solution 2:

I use formencode @validate decorator. It is possible to write custom validator for it but the problem with handling exceptions that occur in the model after validation still exists.

You could write custom action decorator similar to formencode one which will handle your model exceptions and populate c.form_errors.

Solution 3:

Not pretending to be production-ready solution, just as an example. Actually I've copied most of decorator code from pylons.decorators:

from decorator import decorator
from webob import UnicodeMultiDict

classModelException(Exception):
    passdefhandle_exceptions(form):
    defwrapper(fn, self, *args,**kwargs):
        try:
            return fn(self, *args, **kwargs)
        except ModelException, e:
            errors = str(e)
            params = request.POST

            is_unicode_params = isinstance(params, UnicodeMultiDict)
            params = params.mixed()


            request.environ['pylons.routes_dict']['action'] = form
            response = self._dispatch_call()
            # XXX: Legacy WSGIResponse support
            legacy_response = Falseifhasattr(response, 'content'):
                form_content = ''.join(response.content)
                legacy_response = Trueelse:
                form_content = response
                response = self._py_object.response

            # If the form_content is an exception response, return itifhasattr(form_content, '_exception'):
                return form_content

            form_content = htmlfill.render(form_content, defaults=params,
                                           errors=errors)
            if legacy_response:
                # Let the Controller merge the legacy response
                response.content = form_content
                return response
            else:
                return form_content
    return decorator(wrapper)


classHelloFormSchema(Schema):
    allow_extra_fields = True
    filter_extra_fields = True
    name = formencode.validators.UnicodeString(not_empty=True)
    email = formencode.validators.UnicodeString(not_empty=True)

classHelloController(BaseController):
    defnew(self):
        return render('/hello/new.html')

    defview(self):
        return'created'    @handle_exceptions(form='new')    @validate(schema=HelloFormSchema(), form='new')    @restrict("POST")defcreate(self):
        #here is code interacting with model which potentially could raise exception:if self.form_result['name'] == 'doe':
            raise ModelException('user already exists!')
        return redirect(url(controller='hello', action='view'))

new.html:

${h.form(h.url(controller='hello', action='create'), 'post')}
<dl>
    <dt>Name</dt>
    <dd>${h.text('name')}</dd>
    <dt>Email</dt>
    <dd>${h.text('email')}</dd>
    <dd>
    ${h.submit('create', 'Create')}
    </dd>
</dl>
${h.end_form()}

Post a Comment for "Error Handling With Python + Pylons"