7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
1 |
# Copyright 2009 Canonical Ltd. This software is licensed under the
|
2 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
"""Errors used in the lp/code modules."""
|
|
5 |
||
6 |
__metaclass__ = type |
|
7 |
__all__ = [ |
|
8 |
'BadBranchMergeProposalSearchContext', |
|
9 |
'BadStateTransition', |
|
11270.2.1
by Tim Penhey
Move branch errors. |
10 |
'BranchCannotBePrivate', |
11 |
'BranchCannotBePublic', |
|
12 |
'BranchCreationException', |
|
13 |
'BranchCreationForbidden', |
|
14 |
'BranchCreatorNotMemberOfOwnerTeam', |
|
15 |
'BranchCreatorNotOwner', |
|
16 |
'BranchExists', |
|
17 |
'BranchTargetError', |
|
18 |
'BranchTypeError', |
|
7675.729.1
by Aaron Bentley
Raise an exception for duplicate builds. |
19 |
'BuildAlreadyPending', |
11151.1.7
by Paul Hummer
Added new exception to __all__ |
20 |
'BuildNotAllowedForDistro', |
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
21 |
'BranchMergeProposalExists', |
11270.2.1
by Tim Penhey
Move branch errors. |
22 |
'CannotDeleteBranch', |
11270.2.10
by Tim Penhey
Move errors from lp.code.interfaces.linkedbranch to lp.code.errors. |
23 |
'CannotHaveLinkedBranch', |
10454.12.3
by James Westby
Add a way to get an exception if the import has already been requested. |
24 |
'CodeImportAlreadyRequested', |
10454.12.1
by James Westby
Add ICodeImport and associated tests. |
25 |
'CodeImportAlreadyRunning', |
26 |
'CodeImportNotInReviewedState', |
|
7675.430.3
by Tim Penhey
Move the claimReview method to the CodeReviewVoteReference. |
27 |
'ClaimReviewFailed', |
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
28 |
'InvalidBranchMergeProposal', |
7675.887.21
by Paul Hummer
Added IBranch.setMergeQueueConfig with accompanying tests |
29 |
'InvalidMergeQueueConfig', |
11270.2.11
by Tim Penhey
Move InvalidNamespace from lp.code.interfaces.branchnamespace to lp.code.errors |
30 |
'InvalidNamespace', |
11270.2.10
by Tim Penhey
Move errors from lp.code.interfaces.linkedbranch to lp.code.errors. |
31 |
'NoLinkedBranch', |
11270.2.1
by Tim Penhey
Move branch errors. |
32 |
'NoSuchBranch', |
11236.1.1
by Aaron Bentley
Attempting to use a private branch in a SourcePackageRecipe errors. |
33 |
'PrivateBranchRecipe', |
7675.429.12
by Tim Penhey
Allow the deletion of pending reviews. |
34 |
'ReviewNotPending', |
13084.5.2
by Aaron Bentley
Raise StaleLastMirrored as needed. |
35 |
'StaleLastMirrored', |
10979.1.10
by Paul Hummer
Moved TooManyBuilds to lp.code.errors |
36 |
'TooManyBuilds', |
10979.1.8
by Paul Hummer
Fixed import error |
37 |
'TooNewRecipeFormat', |
10379.2.3
by Michael Hudson
acquireBranchToPull changes |
38 |
'UnknownBranchTypeError', |
7675.429.16
by Tim Penhey
Move validation out into separate methods. |
39 |
'UserHasExistingReview', |
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
40 |
'UserNotBranchReviewer', |
41 |
'WrongBranchMergeProposal', |
|
42 |
]
|
|
43 |
||
12252.1.1
by j.c.sackett
Added webservice error and tests for CannotDeleteBranch |
44 |
import httplib |
45 |
||
12261.2.3
by Tim Penhey
Start hacking. |
46 |
from bzrlib.plugins.builder.recipe import RecipeParseError |
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
47 |
from lazr.restful.declarations import error_status |
10466.1.5
by Paul Hummer
Better solution! |
48 |
|
11270.2.1
by Tim Penhey
Move branch errors. |
49 |
from lp.app.errors import NameLookupFailed |
50 |
||
12261.2.3
by Tim Penhey
Start hacking. |
51 |
# Annotate the RecipeParseError's with a 400 webservice status.
|
13228.3.11
by Francis J. Lacoste
More constants conversion. |
52 |
error_status(httplib.BAD_REQUEST)(RecipeParseError) |
12261.2.3
by Tim Penhey
Start hacking. |
53 |
|
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
54 |
|
55 |
class BadBranchMergeProposalSearchContext(Exception): |
|
56 |
"""The context is not valid for a branch merge proposal search."""
|
|
57 |
||
58 |
||
59 |
class BadStateTransition(Exception): |
|
60 |
"""The user requested a state transition that is not possible."""
|
|
61 |
||
62 |
||
11270.2.1
by Tim Penhey
Move branch errors. |
63 |
class BranchCreationException(Exception): |
64 |
"""Base class for branch creation exceptions."""
|
|
65 |
||
66 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
67 |
@error_status(httplib.CONFLICT) |
11270.2.1
by Tim Penhey
Move branch errors. |
68 |
class BranchExists(BranchCreationException): |
69 |
"""Raised when creating a branch that already exists."""
|
|
70 |
||
71 |
def __init__(self, existing_branch): |
|
72 |
# XXX: TimPenhey 2009-07-12 bug=405214: This error
|
|
73 |
# message logic is incorrect, but the exact text is being tested
|
|
74 |
# in branch-xmlrpc.txt.
|
|
75 |
params = {'name': existing_branch.name} |
|
76 |
if existing_branch.product is None: |
|
77 |
params['maybe_junk'] = 'junk ' |
|
78 |
params['context'] = existing_branch.owner.name |
|
79 |
else: |
|
80 |
params['maybe_junk'] = '' |
|
81 |
params['context'] = '%s in %s' % ( |
|
82 |
existing_branch.owner.name, existing_branch.product.name) |
|
83 |
message = ( |
|
84 |
'A %(maybe_junk)sbranch with the name "%(name)s" already exists ' |
|
85 |
'for %(context)s.' % params) |
|
86 |
self.existing_branch = existing_branch |
|
87 |
BranchCreationException.__init__(self, message) |
|
88 |
||
89 |
||
90 |
class BranchTargetError(Exception): |
|
91 |
"""Raised when there is an error determining a branch target."""
|
|
92 |
||
93 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
94 |
@error_status(httplib.BAD_REQUEST) |
11270.2.1
by Tim Penhey
Move branch errors. |
95 |
class CannotDeleteBranch(Exception): |
96 |
"""The branch cannot be deleted at this time."""
|
|
97 |
||
98 |
||
99 |
class BranchCreationForbidden(BranchCreationException): |
|
100 |
"""A Branch visibility policy forbids branch creation.
|
|
101 |
||
102 |
The exception is raised if the policy for the product does not allow
|
|
103 |
the creator of the branch to create a branch for that product.
|
|
104 |
"""
|
|
105 |
||
106 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
107 |
@error_status(httplib.BAD_REQUEST) |
11270.2.1
by Tim Penhey
Move branch errors. |
108 |
class BranchCreatorNotMemberOfOwnerTeam(BranchCreationException): |
109 |
"""Branch creator is not a member of the owner team.
|
|
110 |
||
111 |
Raised when a user is attempting to create a branch and set the owner of
|
|
112 |
the branch to a team that they are not a member of.
|
|
113 |
"""
|
|
114 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
115 |
|
116 |
@error_status(httplib.BAD_REQUEST) |
|
11270.2.1
by Tim Penhey
Move branch errors. |
117 |
class BranchCreatorNotOwner(BranchCreationException): |
118 |
"""A user cannot create a branch belonging to another user.
|
|
119 |
||
120 |
Raised when a user is attempting to create a branch and set the owner of
|
|
121 |
the branch to another user.
|
|
122 |
"""
|
|
123 |
||
124 |
||
125 |
class BranchTypeError(Exception): |
|
126 |
"""An operation cannot be performed for a particular branch type.
|
|
127 |
||
128 |
Some branch operations are only valid for certain types of branches. The
|
|
129 |
BranchTypeError exception is raised if one of these operations is called
|
|
130 |
with a branch of the wrong type.
|
|
131 |
"""
|
|
132 |
||
133 |
||
134 |
class BranchCannotBePublic(Exception): |
|
135 |
"""The branch cannot be made public."""
|
|
136 |
||
137 |
||
138 |
class BranchCannotBePrivate(Exception): |
|
139 |
"""The branch cannot be made private."""
|
|
140 |
||
141 |
||
11912.2.1
by Ian Booth
Add back good changes after testfix revert |
142 |
class InvalidBranchException(Exception): |
143 |
"""Base exception for an error resolving a branch for a component.
|
|
144 |
||
145 |
Subclasses should set _msg_template to match their required display
|
|
146 |
message.
|
|
147 |
"""
|
|
148 |
||
149 |
_msg_template = "Invalid branch for: %s" |
|
150 |
||
151 |
def __init__(self, component): |
|
152 |
self.component = component |
|
153 |
# It's expected that components have a name attribute,
|
|
154 |
# so let's assume they will and deal with any error if it occurs.
|
|
155 |
try: |
|
156 |
component_name = component.name |
|
157 |
except AttributeError: |
|
158 |
component_name = str(component) |
|
159 |
# The display_message contains something readable for the user.
|
|
160 |
self.display_message = self._msg_template % component_name |
|
161 |
Exception.__init__(self, self._msg_template % (repr(component),)) |
|
162 |
||
163 |
||
164 |
class CannotHaveLinkedBranch(InvalidBranchException): |
|
11270.2.10
by Tim Penhey
Move errors from lp.code.interfaces.linkedbranch to lp.code.errors. |
165 |
"""Raised when we try to get the linked branch for a thing that can't."""
|
11270.2.1
by Tim Penhey
Move branch errors. |
166 |
|
11912.2.1
by Ian Booth
Add back good changes after testfix revert |
167 |
_msg_template = "%s cannot have linked branches." |
11270.2.1
by Tim Penhey
Move branch errors. |
168 |
|
169 |
||
7675.430.3
by Tim Penhey
Move the claimReview method to the CodeReviewVoteReference. |
170 |
class ClaimReviewFailed(Exception): |
171 |
"""The user cannot claim the pending review."""
|
|
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
172 |
|
173 |
||
174 |
class InvalidBranchMergeProposal(Exception): |
|
175 |
"""Raised during the creation of a new branch merge proposal.
|
|
176 |
||
177 |
The text of the exception is the rule violation.
|
|
178 |
"""
|
|
179 |
||
180 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
181 |
@error_status(httplib.BAD_REQUEST) |
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
182 |
class BranchMergeProposalExists(InvalidBranchMergeProposal): |
183 |
"""Raised if there is already a matching BranchMergeProposal."""
|
|
10454.10.13
by James Westby
Various fixes from Aarons review, thanks. |
184 |
|
13278.2.2
by Aaron Bentley
Ensure error text is consistent. |
185 |
def __init__(self, existing_proposal): |
186 |
super(BranchMergeProposalExists, self).__init__( |
|
187 |
'There is already a branch merge proposal registered for '
|
|
188 |
'branch %s to land on %s that is still active.' % |
|
189 |
(existing_proposal.source_branch.displayname, |
|
190 |
existing_proposal.target_branch.displayname)) |
|
191 |
self.existing_proposal = existing_proposal |
|
192 |
||
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
193 |
|
11270.2.11
by Tim Penhey
Move InvalidNamespace from lp.code.interfaces.branchnamespace to lp.code.errors |
194 |
class InvalidNamespace(Exception): |
195 |
"""Raised when someone tries to lookup a namespace with a bad name.
|
|
196 |
||
12221.1.7
by Jeroen Vermeulen
s/Unparseable/Unparsable/g, plus lint. |
197 |
By 'bad', we mean that the name is unparsable. It might be too short, too
|
11270.2.11
by Tim Penhey
Move InvalidNamespace from lp.code.interfaces.branchnamespace to lp.code.errors |
198 |
long or malformed in some other way.
|
199 |
"""
|
|
200 |
||
201 |
def __init__(self, name): |
|
202 |
self.name = name |
|
203 |
Exception.__init__( |
|
204 |
self, "Cannot understand namespace name: '%s'" % (name,)) |
|
205 |
||
206 |
||
11912.2.1
by Ian Booth
Add back good changes after testfix revert |
207 |
class NoLinkedBranch(InvalidBranchException): |
11270.2.10
by Tim Penhey
Move errors from lp.code.interfaces.linkedbranch to lp.code.errors. |
208 |
"""Raised when there's no linked branch for a thing."""
|
209 |
||
11912.2.1
by Ian Booth
Add back good changes after testfix revert |
210 |
_msg_template = "%s has no linked branch." |
11270.2.10
by Tim Penhey
Move errors from lp.code.interfaces.linkedbranch to lp.code.errors. |
211 |
|
212 |
||
213 |
class NoSuchBranch(NameLookupFailed): |
|
214 |
"""Raised when we try to load a branch that does not exist."""
|
|
215 |
||
216 |
_message_prefix = "No such branch" |
|
217 |
||
218 |
||
13084.5.2
by Aaron Bentley
Raise StaleLastMirrored as needed. |
219 |
class StaleLastMirrored(Exception): |
220 |
"""Raised when last_mirrored_id is out of date with on-disk value."""
|
|
221 |
||
222 |
def __init__(self, db_branch, info): |
|
223 |
"""Constructor.
|
|
224 |
||
225 |
:param db_branch: The database branch.
|
|
226 |
:param info: A dict of information about the branch, as produced by
|
|
227 |
lp.codehosting.bzrutils.get_branch_info
|
|
228 |
"""
|
|
229 |
self.db_branch = db_branch |
|
230 |
self.info = info |
|
231 |
Exception.__init__( |
|
232 |
self, |
|
233 |
'Database last_mirrored_id %s does not match on-disk value %s' % |
|
234 |
(db_branch.last_mirrored_id, self.info['last_revision_id'])) |
|
235 |
||
236 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
237 |
@error_status(httplib.BAD_REQUEST) |
11236.1.1
by Aaron Bentley
Attempting to use a private branch in a SourcePackageRecipe errors. |
238 |
class PrivateBranchRecipe(Exception): |
239 |
||
240 |
def __init__(self, branch): |
|
241 |
message = ( |
|
242 |
'Recipe may not refer to private branch: %s' % |
|
243 |
branch.bzr_identity) |
|
244 |
self.branch = branch |
|
245 |
Exception.__init__(self, message) |
|
246 |
||
247 |
||
7675.429.12
by Tim Penhey
Allow the deletion of pending reviews. |
248 |
class ReviewNotPending(Exception): |
249 |
"""The requested review is not in a pending state."""
|
|
250 |
||
251 |
||
7675.429.16
by Tim Penhey
Move validation out into separate methods. |
252 |
class UserHasExistingReview(Exception): |
253 |
"""The user has an existing review."""
|
|
254 |
||
255 |
||
7675.429.3
by Tim Penhey
Move merge proposal errors to lp.code.errors. |
256 |
class UserNotBranchReviewer(Exception): |
257 |
"""The user who attempted to review the merge proposal isn't a reviewer.
|
|
258 |
||
259 |
A specific reviewer may be set on a branch. If a specific reviewer
|
|
260 |
isn't set then any user in the team of the owner of the branch is
|
|
261 |
considered a reviewer.
|
|
262 |
"""
|
|
263 |
||
264 |
||
265 |
class WrongBranchMergeProposal(Exception): |
|
266 |
"""The comment requested is not associated with this merge proposal."""
|
|
10379.2.3
by Michael Hudson
acquireBranchToPull changes |
267 |
|
268 |
||
269 |
class UnknownBranchTypeError(Exception): |
|
270 |
"""Raised when the user specifies an unrecognized branch type."""
|
|
10454.12.1
by James Westby
Add ICodeImport and associated tests. |
271 |
|
272 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
273 |
@error_status(httplib.BAD_REQUEST) |
10454.12.1
by James Westby
Add ICodeImport and associated tests. |
274 |
class CodeImportNotInReviewedState(Exception): |
275 |
"""Raised when the user requests an import of a non-automatic import."""
|
|
10454.12.7
by James Westby
Fix formatting of error classes. |
276 |
|
10454.12.3
by James Westby
Add a way to get an exception if the import has already been requested. |
277 |
|
278 |
class CodeImportAlreadyRequested(Exception): |
|
279 |
"""Raised when the user requests an import that is already requested."""
|
|
280 |
||
10454.12.4
by James Westby
Use the new method from the existing browser code. |
281 |
def __init__(self, msg, requesting_user): |
282 |
super(CodeImportAlreadyRequested, self).__init__(msg) |
|
283 |
self.requesting_user = requesting_user |
|
284 |
||
10454.12.3
by James Westby
Add a way to get an exception if the import has already been requested. |
285 |
|
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
286 |
@error_status(httplib.BAD_REQUEST) |
10454.12.1
by James Westby
Add ICodeImport and associated tests. |
287 |
class CodeImportAlreadyRunning(Exception): |
288 |
"""Raised when the user requests an import that is already running."""
|
|
10454.12.7
by James Westby
Fix formatting of error classes. |
289 |
|
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
290 |
|
291 |
@error_status(httplib.BAD_REQUEST) |
|
10979.1.6
by Paul Hummer
Fixed lint, moved the exception |
292 |
class TooNewRecipeFormat(Exception): |
293 |
"""The format of the recipe supplied was too new."""
|
|
294 |
||
295 |
def __init__(self, supplied_format, newest_supported): |
|
296 |
super(TooNewRecipeFormat, self).__init__() |
|
297 |
self.supplied_format = supplied_format |
|
298 |
self.newest_supported = newest_supported |
|
10979.1.10
by Paul Hummer
Moved TooManyBuilds to lp.code.errors |
299 |
|
300 |
||
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
301 |
@error_status(httplib.BAD_REQUEST) |
7675.729.1
by Aaron Bentley
Raise an exception for duplicate builds. |
302 |
class RecipeBuildException(Exception): |
10979.1.10
by Paul Hummer
Moved TooManyBuilds to lp.code.errors |
303 |
|
7675.729.1
by Aaron Bentley
Raise an exception for duplicate builds. |
304 |
def __init__(self, recipe, distroseries, template): |
10979.1.10
by Paul Hummer
Moved TooManyBuilds to lp.code.errors |
305 |
self.recipe = recipe |
306 |
self.distroseries = distroseries |
|
7675.729.1
by Aaron Bentley
Raise an exception for duplicate builds. |
307 |
msg = template % {'recipe': recipe, 'distroseries': distroseries} |
10979.1.10
by Paul Hummer
Moved TooManyBuilds to lp.code.errors |
308 |
Exception.__init__(self, msg) |
7675.729.1
by Aaron Bentley
Raise an exception for duplicate builds. |
309 |
|
310 |
||
311 |
class TooManyBuilds(RecipeBuildException): |
|
312 |
"""A build was requested that exceeded the quota."""
|
|
313 |
||
314 |
def __init__(self, recipe, distroseries): |
|
315 |
RecipeBuildException.__init__( |
|
316 |
self, recipe, distroseries, |
|
317 |
'You have exceeded your quota for recipe %(recipe)s for' |
|
318 |
' distroseries %(distroseries)s') |
|
319 |
||
320 |
||
321 |
class BuildAlreadyPending(RecipeBuildException): |
|
322 |
"""A build was requested when an identical build was already pending."""
|
|
323 |
||
324 |
def __init__(self, recipe, distroseries): |
|
325 |
RecipeBuildException.__init__( |
|
326 |
self, recipe, distroseries, |
|
327 |
'An identical build of this recipe is already pending.') |
|
11151.1.6
by Paul Hummer
Added specific instruction |
328 |
|
329 |
||
330 |
class BuildNotAllowedForDistro(RecipeBuildException): |
|
11151.1.12
by Paul Hummer
Better docstring in lp.code.errors |
331 |
"""A build was requested against an unsupported distroseries."""
|
11151.1.6
by Paul Hummer
Added specific instruction |
332 |
|
333 |
def __init__(self, recipe, distroseries): |
|
334 |
RecipeBuildException.__init__( |
|
335 |
self, recipe, distroseries, |
|
336 |
'A build against this distro is not allowed.') |
|
7675.887.21
by Paul Hummer
Added IBranch.setMergeQueueConfig with accompanying tests |
337 |
|
7675.887.29
by Paul Hummer
Extra line for PEP 8 |
338 |
|
13228.3.9
by Francis J. Lacoste
Convert all webservice_error into error_status and use httplib constants. |
339 |
@error_status(httplib.BAD_REQUEST) |
7675.887.21
by Paul Hummer
Added IBranch.setMergeQueueConfig with accompanying tests |
340 |
class InvalidMergeQueueConfig(Exception): |
341 |
"""The config specified is not a valid JSON string."""
|
|
342 |
||
343 |
def __init__(self): |
|
344 |
message = ('The configuration specified is not a valid JSON string.') |
|
345 |
Exception.__init__(self, message) |