okina: refine errors handling (#31557)
This commit is contained in:
parent
c2bf9eb3b0
commit
1d798fb874
|
@ -36,24 +36,41 @@ class Okina(BaseResource):
|
|||
class Meta:
|
||||
verbose_name = _('Okina')
|
||||
|
||||
def request(self, endpoint, payload=None, result_is_json=True):
|
||||
def request(self, endpoint, payload=None, result_is_json=True, result_is_list=True):
|
||||
url = self.service_url + endpoint
|
||||
auth = (self.username, self.password)
|
||||
headers = {}
|
||||
if result_is_json:
|
||||
headers['Accept'] = 'application/json'
|
||||
if payload is None:
|
||||
result = self.requests.get(url, auth=auth, headers=headers)
|
||||
response = self.requests.get(url, auth=auth, headers=headers)
|
||||
else:
|
||||
headers['Content-Type'] = 'application/json'
|
||||
data = json.dumps(payload)
|
||||
result = self.requests.post(url, data=data, auth=auth, headers=headers)
|
||||
if result.status_code in (401, 403):
|
||||
raise APIError(result.json()['message'], http_status=500)
|
||||
if result_is_json:
|
||||
return result.json()
|
||||
else:
|
||||
return result
|
||||
response = self.requests.post(url, data=data, auth=auth, headers=headers)
|
||||
if not result_is_json:
|
||||
if response.status_code // 100 != 2:
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
data = {'message': 'HTTP request failed'}
|
||||
raise APIError('%s (HTTP error %s)' % (data.get('message'), response.status_code), data=data)
|
||||
return response
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
raise APIError('bad JSON response: %r' % response.content)
|
||||
if response.status_code in (401, 403):
|
||||
raise APIError('%s (%s)' % (data.get('message'), response.status_code), data=data)
|
||||
if result_is_list and not isinstance(data, list):
|
||||
raise APIError('response is not a list', data=data)
|
||||
if response.status_code // 100 != 2:
|
||||
data = {
|
||||
'status_code': response.status_code,
|
||||
'payload': data,
|
||||
}
|
||||
raise APIError('HTTP request failed, error %s' % response.status_code, data=data)
|
||||
return data
|
||||
|
||||
@endpoint()
|
||||
def cities(self, request):
|
||||
|
@ -178,12 +195,12 @@ class Okina(BaseResource):
|
|||
raise APIError('payload must be a JSON object', http_status=400)
|
||||
if not isinstance(payload, dict):
|
||||
raise APIError('payload must be a dict', http_status=400)
|
||||
return {'data': self.request('subscribers', payload)}
|
||||
return {'data': self.request('subscribers', payload, result_is_list=False)}
|
||||
|
||||
@endpoint(name='subscriber', pattern='^(?P<subscriber_id>\d+)/*$',
|
||||
methods=['get'], perm='can_access')
|
||||
def get_subscriber(self, request, subscriber_id):
|
||||
return {'data': self.request('subscribers/%s' % subscriber_id)}
|
||||
return {'data': self.request('subscribers/%s' % subscriber_id, result_is_list=False)}
|
||||
|
||||
@endpoint(name='subscriber', pattern='^(?P<subscriber_id>\d+)/qrcode/*$',
|
||||
perm='can_access')
|
||||
|
@ -205,9 +222,9 @@ class Okina(BaseResource):
|
|||
raise APIError('payload must be a JSON object', http_status=400)
|
||||
if not isinstance(payload, dict):
|
||||
raise APIError('payload must be a dict', http_status=400)
|
||||
return {'data': self.request('subscriptions', payload)}
|
||||
return {'data': self.request('subscriptions', payload, result_is_list=False)}
|
||||
|
||||
@endpoint(name='subscription', pattern='^(?P<subscription_id>\d+)/*$',
|
||||
methods=['get'], perm='can_access')
|
||||
def get_subscription(self, request, subscription_id):
|
||||
return {'data': self.request('subscriptions/%s' % subscription_id)}
|
||||
return {'data': self.request('subscriptions/%s' % subscription_id, result_is_list=False)}
|
||||
|
|
|
@ -1506,22 +1506,24 @@ def test_okina_errors(app, okina):
|
|||
(200, '<h1>Welcome</h1>'), # bad json
|
||||
(403, '<h1>Bad creds</h1>'),
|
||||
(404, '<h1>Not Found</h1>'),
|
||||
(400, '{"message": "bad request"}'),
|
||||
(400, '[{"message": "bad request"}]'),
|
||||
(500, '<h1>Crash</h1>'),
|
||||
):
|
||||
requests_get.return_value = utils.FakedResponse(content=response[1],
|
||||
status_code=response[0])
|
||||
resp = app.get('/okina/test/cities', status=500)
|
||||
resp = app.get('/okina/test/cities', status=200)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['data'] == None
|
||||
if resp.json['data'] and 'status_code' in resp.json['data']:
|
||||
assert resp.json['data']['status_code'] == response[0]
|
||||
|
||||
# "normal" 401/403 response, ie problem with login/password
|
||||
for status_code in (401, 403):
|
||||
requests_get.return_value = utils.FakedResponse(content='''{"message": "Invalid credentials",
|
||||
"code": 4, "status" : %d}''' % status_code, status_code=status_code)
|
||||
resp = app.get('/okina/test/cities', status=500)
|
||||
resp = app.get('/okina/test/cities', status=200)
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == "Invalid credentials"
|
||||
assert resp.json['data'] is None
|
||||
assert resp.json['err_desc'].startswith("Invalid credentials")
|
||||
|
||||
def test_okina_suscribe(app, okina):
|
||||
|
||||
|
@ -1574,23 +1576,15 @@ def test_okina_suscribe(app, okina):
|
|||
requests_get.return_value = utils.FakedResponse(content=QRCODE_400,
|
||||
headers={'Content-Type': 'application/json' },
|
||||
status_code=400)
|
||||
resp = app.get(endpoint, status=400)
|
||||
resp = app.get(endpoint, status=200)
|
||||
assert requests_get.call_count == 2
|
||||
assert resp.json == {
|
||||
u'err': 1,
|
||||
u'err_class': u'passerelle.utils.jsonresponse.APIError',
|
||||
u'err_desc': u'Subscriber with ID 123 has no passcard number to generate qr code from.',
|
||||
u'data': None,
|
||||
}
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'].startswith('Subscriber with ID 123 has no passcard number to generate qr code from.')
|
||||
|
||||
requests_get.return_value = utils.FakedResponse(content=QRCODE_404,
|
||||
headers={'Content-Type': 'application/json' },
|
||||
status_code=404)
|
||||
resp = app.get(endpoint, status=404)
|
||||
resp = app.get(endpoint, status=200)
|
||||
assert requests_get.call_count == 3
|
||||
assert resp.json == {
|
||||
u'err': 1,
|
||||
u'err_class': u'passerelle.utils.jsonresponse.APIError',
|
||||
u'err_desc': u'Subscriber with ID 123 not found.',
|
||||
u'data': None,
|
||||
}
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'].startswith('Subscriber with ID 123 not found.')
|
||||
|
|
Loading…
Reference in New Issue