|
1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
3 # |
|
4 # This file is part of CubicWeb. |
|
5 # |
|
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
|
7 # terms of the GNU Lesser General Public License as published by the Free |
|
8 # Software Foundation, either version 2.1 of the License, or (at your option) |
|
9 # any later version. |
|
10 # |
|
11 # CubicWeb is distributed in the hope that it will be useful, but WITHOUT |
|
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
|
14 # details. |
|
15 # |
|
16 # You should have received a copy of the GNU Lesser General Public License along |
|
17 # with CubicWeb. If not, see <http://www.gnu.org/licenses/>. |
|
18 """Exceptions shared by different cubicweb packages.""" |
|
19 |
|
20 __docformat__ = "restructuredtext en" |
|
21 |
|
22 from warnings import warn |
|
23 |
|
24 from six import PY3, text_type |
|
25 |
|
26 from logilab.common.decorators import cachedproperty |
|
27 |
|
28 from yams import ValidationError |
|
29 |
|
30 # abstract exceptions ######################################################### |
|
31 |
|
32 class CubicWebException(Exception): |
|
33 """base class for cubicweb server exception""" |
|
34 msg = "" |
|
35 def __unicode__(self): |
|
36 if self.msg: |
|
37 if self.args: |
|
38 return self.msg % tuple(self.args) |
|
39 else: |
|
40 return self.msg |
|
41 else: |
|
42 return u' '.join(text_type(arg) for arg in self.args) |
|
43 __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8') |
|
44 |
|
45 class ConfigurationError(CubicWebException): |
|
46 """a misconfiguration error""" |
|
47 |
|
48 class InternalError(CubicWebException): |
|
49 """base class for exceptions which should not occur""" |
|
50 |
|
51 class SecurityError(CubicWebException): |
|
52 """base class for cubicweb server security exceptions""" |
|
53 |
|
54 class RepositoryError(CubicWebException): |
|
55 """base class for repository exceptions""" |
|
56 |
|
57 class SourceException(CubicWebException): |
|
58 """base class for source exceptions""" |
|
59 |
|
60 class CubicWebRuntimeError(CubicWebException): |
|
61 """base class for runtime exceptions""" |
|
62 |
|
63 # repository exceptions ####################################################### |
|
64 |
|
65 class ConnectionError(RepositoryError): |
|
66 """raised when a bad connection id is given or when an attempt to establish |
|
67 a connection failed |
|
68 """ |
|
69 |
|
70 class AuthenticationError(ConnectionError): |
|
71 """raised when an attempt to establish a connection failed due to wrong |
|
72 connection information (login / password or other authentication token) |
|
73 """ |
|
74 |
|
75 class BadConnectionId(ConnectionError): |
|
76 """raised when a bad connection id is given""" |
|
77 |
|
78 class UnknownEid(RepositoryError): |
|
79 """the eid is not defined in the system tables""" |
|
80 msg = 'No entity with eid %s in the repository' |
|
81 |
|
82 class UniqueTogetherError(RepositoryError): |
|
83 """raised when a unique_together constraint caused an IntegrityError""" |
|
84 def __init__(self, session, **kwargs): |
|
85 self.session = session |
|
86 assert 'rtypes' in kwargs or 'cstrname' in kwargs |
|
87 self.kwargs = kwargs |
|
88 # fill cache while the session is open |
|
89 self.rtypes |
|
90 |
|
91 @cachedproperty |
|
92 def rtypes(self): |
|
93 if 'rtypes' in self.kwargs: |
|
94 return self.kwargs['rtypes'] |
|
95 cstrname = unicode(self.kwargs['cstrname']) |
|
96 cstr = self.session.find('CWUniqueTogetherConstraint', name=cstrname).one() |
|
97 return sorted(rtype.name for rtype in cstr.relations) |
|
98 |
|
99 @cachedproperty |
|
100 def args(self): |
|
101 warn('[3.18] UniqueTogetherError.args is deprecated, just use ' |
|
102 'the .rtypes accessor.', |
|
103 DeprecationWarning) |
|
104 # the first argument, etype, is never used and was never garanteed anyway |
|
105 return None, self.rtypes |
|
106 |
|
107 |
|
108 class ViolatedConstraint(RepositoryError): |
|
109 def __init__(self, cnx, cstrname): |
|
110 self.cnx = cnx |
|
111 self.cstrname = cstrname |
|
112 |
|
113 |
|
114 # security exceptions ######################################################### |
|
115 |
|
116 class Unauthorized(SecurityError): |
|
117 """raised when a user tries to perform an action without sufficient |
|
118 credentials |
|
119 """ |
|
120 msg = 'You are not allowed to perform this operation' |
|
121 msg1 = 'You are not allowed to perform %s operation on %s' |
|
122 var = None |
|
123 |
|
124 def __str__(self): |
|
125 try: |
|
126 if self.args and len(self.args) == 2: |
|
127 return self.msg1 % self.args |
|
128 if self.args: |
|
129 return ' '.join(self.args) |
|
130 return self.msg |
|
131 except Exception as ex: |
|
132 return str(ex) |
|
133 |
|
134 class Forbidden(SecurityError): |
|
135 """raised when a user tries to perform a forbidden action |
|
136 """ |
|
137 |
|
138 # source exceptions ########################################################### |
|
139 |
|
140 class EidNotInSource(SourceException): |
|
141 """trying to access an object with a particular eid from a particular |
|
142 source has failed |
|
143 """ |
|
144 msg = 'No entity with eid %s in %s' |
|
145 |
|
146 |
|
147 # registry exceptions ######################################################### |
|
148 |
|
149 # pre 3.15 bw compat |
|
150 from logilab.common.registry import RegistryException, ObjectNotFound, NoSelectableObject |
|
151 |
|
152 class UnknownProperty(RegistryException): |
|
153 """property found in database but unknown in registry""" |
|
154 |
|
155 # query exception ############################################################# |
|
156 |
|
157 class QueryError(CubicWebRuntimeError): |
|
158 """a query try to do something it shouldn't""" |
|
159 |
|
160 class NotAnEntity(CubicWebRuntimeError): |
|
161 """raised when get_entity is called for a column which doesn't contain |
|
162 a non final entity |
|
163 """ |
|
164 |
|
165 class MultipleResultsError(CubicWebRuntimeError): |
|
166 """raised when ResultSet.one() is called on a resultset with multiple rows |
|
167 of multiple columns. |
|
168 """ |
|
169 |
|
170 class NoResultError(CubicWebRuntimeError): |
|
171 """raised when no result is found but at least one is expected. |
|
172 """ |
|
173 |
|
174 class UndoTransactionException(QueryError): |
|
175 """Raised when undoing a transaction could not be performed completely. |
|
176 |
|
177 Note that : |
|
178 1) the partial undo operation might be acceptable |
|
179 depending upon the final application |
|
180 |
|
181 2) the undo operation can also fail with a `ValidationError` in |
|
182 cases where the undoing breaks integrity constraints checked |
|
183 immediately. |
|
184 |
|
185 3) It might be that neither of those exception is raised but a |
|
186 subsequent `commit` might raise a `ValidationError` in cases |
|
187 where the undoing breaks integrity constraints checked at |
|
188 commit time. |
|
189 |
|
190 :type txuuix: int |
|
191 :param txuuid: Unique identifier of the partially undone transaction |
|
192 |
|
193 :type errors: list |
|
194 :param errors: List of errors occurred during undoing |
|
195 """ |
|
196 msg = u"The following error(s) occurred while undoing transaction #%d : %s" |
|
197 |
|
198 def __init__(self, txuuid, errors): |
|
199 super(UndoTransactionException, self).__init__(txuuid, errors) |
|
200 self.txuuid = txuuid |
|
201 self.errors = errors |
|
202 |
|
203 # tools exceptions ############################################################ |
|
204 |
|
205 class ExecutionError(Exception): |
|
206 """server execution control error (already started, not running...)""" |
|
207 |
|
208 # pylint: disable=W0611 |
|
209 from logilab.common.clcommands import BadCommandUsage |