# HG changeset patch # User Sylvain Thénault # Date 1286919395 -7200 # Node ID 6401a9d0b5aa5eaa3a2254f18f374b9c84f7e301 # Parent 11f9fbf6a645a415f1686b3a177ece7366a21f86 [architecture] introduce adapter to ease transformation of errors before display to the end user. Use it for UniqueTogetherError first diff -r 11f9fbf6a645 -r 6401a9d0b5aa entities/adapters.py --- 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)) diff -r 11f9fbf6a645 -r 6401a9d0b5aa selectors.py --- 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.""" diff -r 11f9fbf6a645 -r 6401a9d0b5aa server/repository.py --- 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