_exceptions.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Wed, 08 Jan 2014 12:09:44 +0100
changeset 9375 8e88576787c3
parent 9347 bd841d6ae723
child 9467 ad66d7b3fd48
child 9517 3338b2205ea3
permissions -rw-r--r--
[schema] fix unique together index handling We now provide a more compact indexname, using the schema constraint entity type and the position of the columns set in the entity type unique constraints list. This avoids a nasty name truncation issue. The UniqueTogetherError object is made smarter: it computes the rtypes, abstracting the underlying backend (pg/sqlserver vs sqlite). The `user friendly` adapter is much simplified since there is no longer any truncation issue. Uses a new logilab.database version (ticket #151507) and a new yams version (ticket #189299) Closes #2514939 [jcr: disable hooks when temporarily dropping CWUniqueTogetherConstraint entities]

# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
#
# CubicWeb is free software: you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 of the License, or (at your option)
# any later version.
#
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
"""Exceptions shared by different cubicweb packages."""

__docformat__ = "restructuredtext en"

from warnings import warn

from logilab.common.decorators import cachedproperty

from yams import ValidationError as ValidationError

# abstract exceptions #########################################################

class CubicWebException(Exception):
    """base class for cubicweb server exception"""
    msg = ""
    def __str__(self):
        if self.msg:
            if self.args:
                return self.msg % tuple(self.args)
            else:
                return self.msg
        else:
            return u' '.join(unicode(arg) for arg in self.args)

class ConfigurationError(CubicWebException):
    """a misconfiguration error"""

class InternalError(CubicWebException):
    """base class for exceptions which should not occurs"""

class SecurityError(CubicWebException):
    """base class for cubicweb server security exception"""

class RepositoryError(CubicWebException):
    """base class for repository exceptions"""

class SourceException(CubicWebException):
    """base class for source exceptions"""

class CubicWebRuntimeError(CubicWebException):
    """base class for runtime exceptions"""

# repository exceptions #######################################################

class ConnectionError(RepositoryError):
    """raised when a bad connection id is given or when an attempt to establish
    a connection failed
    """

class AuthenticationError(ConnectionError):
    """raised when an attempt to establish a connection failed due to wrong
    connection information (login / password or other authentication token)
    """

class BadConnectionId(ConnectionError):
    """raised when a bad connection id is given"""

class UnknownEid(RepositoryError):
    """the eid is not defined in the system tables"""
    msg = 'No entity with eid %s in the repository'

class ETypeNotSupportedBySources(RepositoryError, InternalError):
    """no source support an entity type"""
    msg = 'No source supports %r entity\'s type'

class MultiSourcesError(RepositoryError, InternalError):
    """usually due to bad multisources configuration or rql query"""

class UniqueTogetherError(RepositoryError):
    """raised when a unique_together constraint caused an IntegrityError"""
    def __init__(self, session, **kwargs):
        self.session = session
        assert 'rtypes' in kwargs or 'cstrname' in kwargs
        self.kwargs = kwargs

    @cachedproperty
    def rtypes(self):
        if 'rtypes' in self.kwargs:
            return self.kwargs['rtypes']
        cstrname = unicode(self.kwargs['cstrname'])
        cstr = self.session.find('CWUniqueTogetherConstraint', name=cstrname).one()
        return sorted(rtype.name for rtype in cstr.relations)

    @cachedproperty
    def args(self):
        warn('[3.18] UniqueTogetherError.args is deprecated, just use '
             'the .rtypes accessor.',
             DeprecationWarning)
        # the first argument, etype, is never used and was never garanteed anyway
        return None, self.rtypes


# security exceptions #########################################################

class Unauthorized(SecurityError):
    """raised when a user tries to perform an action without sufficient
    credentials
    """
    msg = 'You are not allowed to perform this operation'
    msg1 = 'You are not allowed to perform %s operation on %s'
    var = None

    def __str__(self):
        try:
            if self.args and len(self.args) == 2:
                return self.msg1 % self.args
            if self.args:
                return ' '.join(self.args)
            return self.msg
        except Exception as ex:
            return str(ex)

class Forbidden(SecurityError):
    """raised when a user tries to perform a forbidden action
    """

# source exceptions ###########################################################

class EidNotInSource(SourceException):
    """trying to access an object with a particular eid from a particular
    source has failed
    """
    msg = 'No entity with eid %s in %s'


# registry exceptions #########################################################

# pre 3.15 bw compat
from logilab.common.registry import RegistryException, ObjectNotFound, NoSelectableObject

class UnknownProperty(RegistryException):
    """property found in database but unknown in registry"""

# query exception #############################################################

class QueryError(CubicWebRuntimeError):
    """a query try to do something it shouldn't"""

class NotAnEntity(CubicWebRuntimeError):
    """raised when get_entity is called for a column which doesn't contain
    a non final entity
    """

class MultipleResultsError(CubicWebRuntimeError):
    """raised when ResultSet.one() is called on a resultset with multiple rows
    of multiple columns.
    """

class NoResultError(CubicWebRuntimeError):
    """raised when no result is found but at least one is expected.
    """

class UndoTransactionException(QueryError):
    """Raised when undoing a transaction could not be performed completely.

    Note that :
      1) the partial undo operation might be acceptable
         depending upon the final application

      2) the undo operation can also fail with a `ValidationError` in
         cases where the undoing breaks integrity constraints checked
         immediately.

      3) It might be that neither of those exception is raised but a
         subsequent `commit` might raise a `ValidationError` in cases
         where the undoing breaks integrity constraints checked at
         commit time.

    :type txuuix: int
    :param txuuid: Unique identifier of the partialy undone transaction

    :type errors: list
    :param errors: List of errors occured during undoing
    """
    msg = u"The following error(s) occured while undoing transaction #%d : %s"

    def __init__(self, txuuid, errors):
        super(UndoTransactionException, self).__init__(txuuid, errors)
        self.txuuid = txuuid
        self.errors = errors

# tools exceptions ############################################################

class ExecutionError(Exception):
    """server execution control error (already started, not running...)"""

# pylint: disable=W0611
from logilab.common.clcommands import BadCommandUsage