[architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first
--- a/entities/adapters.py Tue Oct 12 23:34:55 2010 +0200
+++ b/entities/adapters.py Tue Oct 12 23:36:35 2010 +0200
@@ -28,7 +28,8 @@
from logilab.common.decorators import cached
from cubicweb.view import EntityAdapter, implements_adapter_compat
-from cubicweb.selectors import implements, is_instance, relation_possible
+from cubicweb.selectors import (implements, is_instance, relation_possible,
+ match_exception)
from cubicweb.interfaces import IDownloadable, ITree, IProgress, IMileStone
@@ -463,3 +464,24 @@
def contractors(self):
"""returns the list of persons supposed to work on this task"""
raise NotImplementedError
+
+
+# error handling adapters ######################################################
+
+from cubicweb import UniqueTogetherError
+
+class IUserFriendlyError(EntityAdapter):
+ __regid__ = 'IUserFriendlyError'
+ __abstract__ = True
+ def __init__(self, *args, **kwargs):
+ self.exc = kwargs.pop('exc')
+ super(IUserFriendlyError, self).__init__(*args, **kwargs)
+
+
+class IUserFriendlyUniqueTogether(IUserFriendlyError):
+ __select__ = match_exception(UniqueTogetherError)
+ def raise_user_exception(self):
+ etype, rtypes = self.exc.args
+ msg = self._cw._('violates unique_together constraints (%s)') % (
+ ', '.join(self._cw._(rtypes)))
+ raise ValidationError(self.entity.eid, dict((col, msg) for col in rtypes))
--- a/selectors.py Tue Oct 12 23:34:55 2010 +0200
+++ b/selectors.py Tue Oct 12 23:36:35 2010 +0200
@@ -1430,6 +1430,21 @@
return 0
+class match_exception(ExpectedValueSelector):
+ """Return 1 if a view is specified an as its registry id is in one of the
+ expected view id given to the initializer.
+ """
+ def __init__(self, *expected):
+ assert expected, self
+ self.expected = expected
+
+ @lltrace
+ def __call__(self, cls, req, exc=None, **kwargs):
+ if exc is not None and isinstance(exc, self.expected):
+ return 1
+ return 0
+
+
@objectify_selector
def debug_mode(cls, req, rset=None, **kwargs):
"""Return 1 if running in debug mode."""
--- a/server/repository.py Tue Oct 12 23:34:55 2010 +0200
+++ b/server/repository.py Tue Oct 12 23:36:35 2010 +0200
@@ -1174,11 +1174,9 @@
try:
source.add_entity(session, entity)
except UniqueTogetherError, exc:
- etype, rtypes = exc.args
- problems = {}
- for col in rtypes:
- problems[col] = session._('violates unique_together constraints (%s)') % (','.join(rtypes))
- raise ValidationError(entity.eid, problems)
+ userhdlr = session.vreg['adapters'].select(
+ 'IUserFriendlyError', session, entity=entity, exc=exc)
+ userhdlr.raise_user_exception()
self.add_info(session, entity, source, extid, complete=False)
edited.saved = entity._cw_is_saved = True
# trigger after_add_entity after after_add_relation