使用Python + Pylons的错误处理
如何正确处理Python和Pylons中的错误?
假设用户通过一个表单设置密码,但当这个密码通过控制器传递给模型类时,因为密码太短而出现错误。我们应该如何处理这个错误,以便在网页上显示错误信息,而不是整个程序直接跳转到错误页面?
控制器本身是否应该进行错误处理?
我希望我能清楚地表达我的意思。
谢谢。
3 个回答
1
这段话并不是说这是一个可以直接用在生产环境的解决方案,只是一个示例而已。实际上,我大部分的装饰器代码都是从pylons.decorators里复制过来的:
from decorator import decorator
from webob import UnicodeMultiDict
class ModelException(Exception):
pass
def handle_exceptions(form):
def wrapper(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 = False
if hasattr(response, 'content'):
form_content = ''.join(response.content)
legacy_response = True
else:
form_content = response
response = self._py_object.response
# If the form_content is an exception response, return it
if hasattr(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)
class HelloFormSchema(Schema):
allow_extra_fields = True
filter_extra_fields = True
name = formencode.validators.UnicodeString(not_empty=True)
email = formencode.validators.UnicodeString(not_empty=True)
class HelloController(BaseController):
def new(self):
return render('/hello/new.html')
def view(self):
return 'created'
@handle_exceptions(form='new')
@validate(schema=HelloFormSchema(), form='new')
@restrict("POST")
def create(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()}
1
我在使用 formencode 的 @validate 装饰器。虽然可以为它写自定义的验证器,但在验证之后,如果模型出现异常的问题还是存在的。
你可以写一个类似于 formencode 的自定义动作装饰器,这样就能处理你的模型异常,并把错误信息填充到 c.form_errors 中。
2
你们用什么来验证表单呢?我在用 formalchemy。它会用内置的和自定义的验证器来检查输入的数据,并把找到的错误放在一个列表里。然后你可以在你的模板中以任何方式显示这个列表。
文档可以在 这里 找到。