Skip to content

Commit 138caf8

Browse files
stanislavlevincrobinso
authored andcommitted
rest api: Post process bugzilla code on HTTP error
Bugzilla REST API map result codes to HTTP status codes: https://github.com/bugzilla/bugzilla/blob/7581e08f9136ec32219af6c3192e42ff1c8e9691/Bugzilla/WebService/Constants.pm#L262-L287 But python-bugzilla don't propagate those Bugzilla codes. Fixes: #171 Signed-off-by: Stanislav Levin <slev@altlinux.org>
1 parent 6de112f commit 138caf8

4 files changed

Lines changed: 38 additions & 7 deletions

File tree

bugzilla/_backendrest.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88

99
from ._backendbase import _BackendBase
10-
from .exceptions import BugzillaError
10+
from .exceptions import BugzillaError, BugzillaHTTPError
1111
from ._util import listify
1212

1313

@@ -32,6 +32,23 @@ def __init__(self, url, bugzillasession):
3232
#########################
3333
# Internal REST helpers #
3434
#########################
35+
def _handle_error(self, e):
36+
response = getattr(e, "response", None)
37+
if response is None:
38+
raise e
39+
40+
if response.status_code in [400, 401, 404]:
41+
self._handle_error_response(response.text)
42+
raise e
43+
44+
def _handle_error_response(self, text):
45+
try:
46+
result = json.loads(text)
47+
except json.JSONDecodeError:
48+
return
49+
50+
if result.get("error"):
51+
raise BugzillaError(result["message"], code=result["code"])
3552

3653
def _handle_response(self, text):
3754
try:
@@ -55,8 +72,13 @@ def _op(self, method, apiurl, paramdict=None):
5572
else:
5673
data = json.dumps(paramdict or {})
5774

58-
response = self._bugzillasession.request(method, fullurl, data=data,
59-
params=authparams)
75+
try:
76+
response = self._bugzillasession.request(
77+
method, fullurl, data=data, params=authparams
78+
)
79+
except BugzillaHTTPError as e:
80+
self._handle_error(e)
81+
6082
return self._handle_response(response.text)
6183

6284
def _get(self, *args, **kwargs):

bugzilla/_session.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import requests
1111

12+
from .exceptions import BugzillaHTTPError
1213

1314
log = getLogger(__name__)
1415

@@ -106,9 +107,12 @@ def request(self, *args, **kwargs):
106107

107108
try:
108109
response.raise_for_status()
109-
except Exception as e:
110+
except requests.HTTPError as e:
110111
# Scrape the api key out of the returned exception string
111112
message = str(e).replace(self._api_key or "", "")
112-
raise type(e)(message).with_traceback(sys.exc_info()[2])
113+
response = getattr(e, "response", None)
114+
raise BugzillaHTTPError(message, response=response).with_traceback(
115+
sys.exc_info()[2]
116+
)
113117

114118
return response

bugzilla/exceptions.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# This work is licensed under the GNU GPLv2 or later.
22
# See the COPYING file in the top-level directory.
3+
from requests import HTTPError
34

45

56
class BugzillaError(Exception):
@@ -36,3 +37,7 @@ def __init__(self, message, code=None):
3637
if self.code:
3738
message += " (code=%s)" % self.code
3839
Exception.__init__(self, message)
40+
41+
42+
class BugzillaHTTPError(HTTPError):
43+
"""Error raised in the Bugzilla session"""

tests/test_rw_functional.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ def _check_have_admin(bz):
5050
return ret
5151

5252

53-
def test0LoggedInNoCreds():
54-
bz = _open_bz(use_creds=False)
53+
def test0LoggedInNoCreds(backends):
54+
bz = _open_bz(**backends, use_creds=False)
5555
assert not bz.logged_in
5656

5757

0 commit comments

Comments
 (0)