Merge lp:~jelmer/brz/gitlab-422 into lp:brz/3.1

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Jelmer Vernooij
Approved revision: no longer in the source branch.
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/gitlab-422
Merge into: lp:brz/3.1
Diff against target: 183 lines (+48/-15)
3 files modified
breezy/errors.py (+5/-5)
breezy/plugins/gitlab/hoster.py (+31/-10)
breezy/propose.py (+12/-0)
To merge this branch: bzr merge lp:~jelmer/brz/gitlab-422
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve
Review via email: mp+388529@code.launchpad.net

Commit message

Include response data when raising UnexpectedHttpStatus.

Raise more specific error when source branch doesn't derived from target branch.

Description of the change

Include response data when raising UnexpectedHttpStatus.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/errors.py'
2--- breezy/errors.py 2020-07-26 15:29:07 +0000
3+++ breezy/errors.py 2020-08-02 03:22:50 +0000
4@@ -1302,15 +1302,15 @@
5
6 class UnexpectedHttpStatus(InvalidHttpResponse):
7
8- _fmt = "Unexpected HTTP status %(code)d for %(path)s"
9+ _fmt = "Unexpected HTTP status %(code)d for %(path)s: %(extra)s"
10
11- def __init__(self, path, code, msg=None):
12+ def __init__(self, path, code, extra=None):
13 self.path = path
14 self.code = code
15- self.msg = msg
16+ self.extra = extra or ''
17 full_msg = 'status code %d unexpected' % code
18- if msg is not None:
19- full_msg += ': ' + msg
20+ if extra is not None:
21+ full_msg += ': ' + extra
22 InvalidHttpResponse.__init__(
23 self, path, full_msg)
24
25
26=== modified file 'breezy/plugins/gitlab/hoster.py'
27--- breezy/plugins/gitlab/hoster.py 2020-07-26 17:39:41 +0000
28+++ breezy/plugins/gitlab/hoster.py 2020-08-02 03:22:50 +0000
29@@ -77,6 +77,14 @@
30 self.url = url
31
32
33+class GitLabUnprocessable(errors.BzrError):
34+
35+ _fmt = "GitLab can not process request: %(error)s."
36+
37+ def __init__(self, error):
38+ errors.BzrError.__init__(self, error=error)
39+
40+
41 class DifferentGitLabInstances(errors.BzrError):
42
43 _fmt = ("Can't create merge proposals across GitLab instances: "
44@@ -196,6 +204,11 @@
45 return host, project_name, int(parts[-1])
46
47
48+def _unexpected_status(path, response):
49+ raise errors.UnexpectedHttpStatus(
50+ path, response.status, response.data.decode('utf-8', 'replace'))
51+
52+
53 class GitLabMergeProposal(MergeProposal):
54
55 def __init__(self, gl, mr):
56@@ -346,7 +359,7 @@
57 raise KeyError('no such user %s' % username)
58 if response.status == 200:
59 return json.loads(response.data)
60- raise errors.UnexpectedHttpStatus(path, response.status)
61+ _unexpected_status(path, response)
62
63 def _get_user_by_email(self, email):
64 path = 'users?search=%s' % urlutils.quote(str(email), '')
65@@ -358,7 +371,7 @@
66 if len(ret) != 1:
67 raise ValueError('unexpected number of results; %r' % ret)
68 return ret[0]
69- raise errors.UnexpectedHttpStatus(path, response.status)
70+ _unexpected_status(path, response)
71
72 def _get_project(self, project_name):
73 path = 'projects/%s' % urlutils.quote(str(project_name), '')
74@@ -367,7 +380,7 @@
75 raise NoSuchProject(project_name)
76 if response.status == 200:
77 return json.loads(response.data)
78- raise errors.UnexpectedHttpStatus(path, response.status)
79+ _unexpected_status(path, response)
80
81 def _fork_project(self, project_name, timeout=50, interval=5, owner=None):
82 path = 'projects/%s/fork' % urlutils.quote(str(project_name), '')
83@@ -381,7 +394,7 @@
84 resp = json.loads(response.data)
85 raise GitLabConflict(resp.get('message'))
86 if response.status not in (200, 201):
87- raise errors.UnexpectedHttpStatus(path, response.status)
88+ _unexpected_status(path, response)
89 # The response should be valid JSON, but let's ignore it
90 project = json.loads(response.data)
91 # Spin and wait until import_status for new project
92@@ -417,7 +430,7 @@
93 if response.status == 403:
94 raise errors.PermissionDenied(response.text)
95 if response.status != 200:
96- raise errors.UnexpectedHttpStatus(path, response.status)
97+ _unexpected_status(path, response)
98 page = response.getheader("X-Next-Page")
99 for entry in json.loads(response.data):
100 yield entry
101@@ -440,7 +453,7 @@
102 if response.status == 403:
103 raise errors.PermissionDenied(response.text)
104 if response.status != 200:
105- raise errors.UnexpectedHttpStatus(path, response.status)
106+ _unexpected_status(path, response)
107 return json.loads(response.data)
108
109 def _list_projects(self, owner):
110@@ -454,7 +467,7 @@
111 response = self._api_request('PUT', path, fields=mr)
112 if response.status == 200:
113 return json.loads(response.data)
114- raise errors.UnexpectedHttpStatus(path, response.status)
115+ _unexpected_status(path, response)
116
117 def _post_merge_request_note(self, project_id, iid, kwargs):
118 path = 'projects/%s/merge_requests/%s/notes' % (
119@@ -463,7 +476,7 @@
120 if response.status == 201:
121 json.loads(response.data)
122 return
123- raise errors.UnexpectedHttpStatus(path, response.status)
124+ _unexpected_status(path, response)
125
126 def _create_mergerequest(
127 self, title, source_project_id, target_project_id,
128@@ -485,8 +498,11 @@
129 raise errors.PermissionDenied(response.text)
130 if response.status == 409:
131 raise MergeRequestExists()
132+ if response.status == 422:
133+ data = json.loads(response.data)
134+ raise GitLabUnprocessable(data['error'])
135 if response.status != 201:
136- raise errors.UnexpectedHttpStatus(path, response.status)
137+ _unexpected_status(path, response)
138 return json.loads(response.data)
139
140 def get_push_url(self, branch):
141@@ -634,7 +650,7 @@
142 if response.status == 404:
143 raise NoSuchProject(project)
144 if response.status != 202:
145- raise errors.UnexpectedHttpStatus(path, response.status)
146+ _unexpected_status(path, response)
147
148
149 class GitlabMergeProposalBuilder(MergeProposalBuilder):
150@@ -703,6 +719,11 @@
151 merge_request = self.gl._create_mergerequest(**kwargs)
152 except MergeRequestExists:
153 raise MergeProposalExists(self.source_branch.user_url)
154+ except GitLabUnprocessable as e:
155+ if e.error == [
156+ "Source project is not a fork of the target project"]:
157+ raise SourceNotDerivedFromTarget(
158+ self.source_branch, self.target_branch)
159 return GitLabMergeProposal(self.gl, merge_request)
160
161
162
163=== modified file 'breezy/propose.py'
164--- breezy/propose.py 2020-07-24 17:47:14 +0000
165+++ breezy/propose.py 2020-08-02 03:22:50 +0000
166@@ -99,6 +99,18 @@
167 self.hoster = hoster
168
169
170+class SourceNotDerivedFromTarget(errors.BzrError):
171+ """Source branch is not derived from target branch."""
172+
173+ _fmt = ("Source %(source_branch)r not derived from "
174+ "target %(target_branch)r.")
175+
176+ def __init__(self, source_branch, target_branch):
177+ errors.BzrError.__init__(
178+ self, source_branch=source_branch,
179+ target_branch=target_branch)
180+
181+
182 class MergeProposal(object):
183 """A merge proposal.
184

Subscribers

People subscribed via source and target branches