Merge lp:~thumper/launchpad/better-errors-for-translate-path into lp:launchpad

Proposed by Tim Penhey
Status: Merged
Approved by: Robert Collins
Approved revision: no longer in the source branch.
Merged at revision: 11695
Proposed branch: lp:~thumper/launchpad/better-errors-for-translate-path
Merge into: lp:launchpad
Diff against target: 86 lines (+29/-8)
2 files modified
lib/lp/code/xmlrpc/codehosting.py (+11/-2)
lib/lp/code/xmlrpc/tests/test_codehosting.py (+18/-6)
To merge this branch: bzr merge lp:~thumper/launchpad/better-errors-for-translate-path
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) code Approve
Robert Collins (community) release-critical Approve
Launchpad code reviewers release-critical Pending
Review via email: mp+38178@code.launchpad.net

Commit message

Catch the CannotHaveLinkedBranch exception in translatePath

Description of the change

Originally I was wanting to get the nice contextually aware error messages that existed when the bazaar client got full branch names back for official linked branches from the XMLRPC server rather than the +branch/alias that it gets now to enable accessing private official branches and pushing to series branches to create links.

However that isn't possible with the way that bzr and lp communicate with the launchpad transport. Ideally we want to extend bzr to get nicer error messages by having an early smart server message that specifies the branch and read or write needs of the connection.

So... what this branch does is very simple. It catches the CannotHaveLinkedBranch error and makes sure it is passed back the same way the other exceptions are.

tests:
    CodehostingTest

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

"returns XXX" - that will confuse folk ;)

I sometimes find creating a constant tuple for exceptions useful. You might find it nice here.

caught_errors = (...)
except caught_errors:
  ...

mainly useful when you want the same set in multiple places.

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

This is broken in prod, its a regression.

review: Approve (release-critical)
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

One broken comment, otherwise fine. It'd be nice if the surrounding code could be cleaned up someday, but that's not for an RC. Approvedl

review: Approve (code)
Revision history for this message
Jonathan Lange (jml) wrote :

Is the CannotHaveLinkedBranch error still being raised for cases where, actually, a linked branch is possible but none exists? If so, when is that going to be fixed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/xmlrpc/codehosting.py'
2--- lib/lp/code/xmlrpc/codehosting.py 2010-08-20 20:31:18 +0000
3+++ lib/lp/code/xmlrpc/codehosting.py 2010-10-12 04:26:20 +0000
4@@ -42,6 +42,7 @@
5 from lp.code.enums import BranchType
6 from lp.code.errors import (
7 BranchCreationException,
8+ CannotHaveLinkedBranch,
9 InvalidNamespace,
10 NoLinkedBranch,
11 UnknownBranchTypeError,
12@@ -69,7 +70,10 @@
13 IPersonSet,
14 NoSuchPerson,
15 )
16-from lp.registry.interfaces.product import NoSuchProduct
17+from lp.registry.interfaces.product import (
18+ InvalidProductName,
19+ NoSuchProduct,
20+ )
21 from lp.services.scripts.interfaces.scriptactivity import IScriptActivitySet
22 from lp.services.utils import iter_split
23
24@@ -339,7 +343,12 @@
25 raise faults.PathTranslationError(path)
26 branch, trailing = getUtility(
27 IBranchLookup).getByLPPath(lp_path)
28- except (NameLookupFailed, InvalidNamespace, NoLinkedBranch):
29+ except (InvalidProductName, NoLinkedBranch,
30+ CannotHaveLinkedBranch):
31+ # If we get one of these errors, then there is no
32+ # point walking back through the path parts.
33+ break
34+ except (NameLookupFailed, InvalidNamespace):
35 # The reason we're doing it is that getByLPPath thinks
36 # that 'foo/.bzr' is a request for the '.bzr' series
37 # of a product.
38
39=== modified file 'lib/lp/code/xmlrpc/tests/test_codehosting.py'
40--- lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-10-04 19:50:45 +0000
41+++ lib/lp/code/xmlrpc/tests/test_codehosting.py 2010-10-12 04:26:20 +0000
42@@ -645,11 +645,6 @@
43 (branch.control_format, branch.branch_format,
44 branch.repository_format))
45
46- def assertCannotTranslate(self, requester, path):
47- """Assert that we cannot translate 'path'."""
48- fault = self.codehosting_api.translatePath(requester.id, path)
49- self.assertEqual(faults.PathTranslationError(path), fault)
50-
51 def assertNotFound(self, requester, path):
52 """Assert that the given path cannot be found."""
53 if requester not in [LAUNCHPAD_ANONYMOUS, LAUNCHPAD_SERVICES]:
54@@ -684,7 +679,7 @@
55 # couldn't translate.
56 requester = self.factory.makePerson()
57 path = escape(u'/untranslatable')
58- self.assertCannotTranslate(requester, path)
59+ self.assertNotFound(requester, path)
60
61 def test_translatePath_no_preceding_slash(self):
62 requester = self.factory.makePerson()
63@@ -966,6 +961,23 @@
64 path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, product.name)
65 self.assertNotFound(requester, path)
66
67+ def test_translatePath_branch_alias_no_linked_sourcepackage_branch(self):
68+ # translatePath returns a not found when there's no linked branch for
69+ # a distro series source package.
70+ requester = self.factory.makePerson()
71+ sourcepackage = self.factory.makeSourcePackage()
72+ distro = sourcepackage.distribution
73+ path = '/%s/%s/%s' % (
74+ BRANCH_ALIAS_PREFIX, distro.name, sourcepackage.sourcepackagename)
75+ self.assertNotFound(requester, path)
76+
77+ def test_translatePath_branch_alias_invalid_product_name(self):
78+ # translatePath returns a not found when there is an invalid product name.
79+ requester = self.factory.makePerson()
80+ invalid_name = '_' + self.factory.getUniqueString()
81+ path = '/%s/%s' % (BRANCH_ALIAS_PREFIX, invalid_name)
82+ self.assertNotFound(requester, path)
83+
84 def test_translatePath_branch_alias_bzrdir_content(self):
85 # translatePath('/+branch/.bzr/.*') *must* return not found, otherwise
86 # bzr will look for it and we don't have a global bzr dir.