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"