diff --git a/passerelle/apps/esabora/models.py b/passerelle/apps/esabora/models.py index ce591548..1fc786cc 100644 --- a/passerelle/apps/esabora/models.py +++ b/passerelle/apps/esabora/models.py @@ -72,7 +72,7 @@ class Esabora(BaseResource, HTTPResource): url = urllib.parse.urljoin(self.service_url, path) headers = {'Authorization': f'Bearer {self.api_key}'} try: - return self.requests.post(url, json=payload, headers=headers, timeout=5, **kwargs) + response = self.requests.post(url, json=payload, headers=headers, timeout=5, **kwargs) except requests.RequestException as e: raise APIError( 'Esabora platform "%s" connection error: %s' % (self.service_url, exception_to_text(e)), @@ -83,6 +83,26 @@ class Esabora(BaseResource, HTTPResource): 'error': str(e), }, ) + try: + data = response.json() + except requests.JSONDecodeError as e: + raise APIError( + 'Esabora platform "%s" invalid JSON response: %s' % (self.service_url, exception_to_text(e)), + log_error=True, + data={ + 'status_code': response.status_code, + }, + ) + if not response.ok: + raise APIError( + 'Esabora platform "%s" answered with HTTP error' % (self.service_url), + log_error=True, + data={ + 'status_code': response.status_code, + 'content': data, + }, + ) + return data @endpoint( name='do-search', @@ -100,9 +120,7 @@ class Esabora(BaseResource, HTTPResource): for name, value in post_data['criterions'].items() ], } - response = self.post('mult/', payload, params={'task': 'doSearch'}) - response.raise_for_status() - data = response.json() + data = self.post('mult/', payload, params={'task': 'doSearch'}) columns = {slugify(c).replace('-', '_'): c for c in data['columnList']} keys = {slugify(c).replace('-', '_'): c for c in data['keyList']} cleaned_data = { @@ -130,9 +148,7 @@ class Esabora(BaseResource, HTTPResource): endpoint = post_data.pop('endpoint', None) or 'modbdd' payload = get_treatment_payload(post_data) - response = self.post(f'{endpoint}/', payload, params={'task': 'doTreatment'}) - response.raise_for_status() - data = response.json() + data = self.post(f'{endpoint}/', payload, params={'task': 'doTreatment'}) keys = [slugify(c).replace('-', '_') for c in data['keyList']] cleaned_data = esabora_row_to_object([], keys, data) cleaned_data['action'] = data['action'] diff --git a/tests/test_esabora.py b/tests/test_esabora.py index f13a6c52..07d6479b 100644 --- a/tests/test_esabora.py +++ b/tests/test_esabora.py @@ -245,3 +245,31 @@ def test_do_treatment_arbitrary_endpoint(app, connector): assert responses.calls[0].request.params['task'] == 'doTreatment' response_data = json.loads(responses.calls[0].request.body) assert response_data == expected_payload + + +@responses.activate +def test_post_raises_proper_error(app, connector): + url = tests.utils.generic_endpoint_url('esabora', 'do-treatment') + responses.add( + responses.POST, + f'{connector.service_url}addevt/', + json={'foo': 'bar'}, + status=400, + ) + + payload = { + 'endpoint': 'addevt', + 'treatment_name': 'Import Event', + 'Adresse_Latitude': 12.3, + 'Adresse_Ville': 'Marseille', + } + + expected_response = { + 'err': 1, + 'err_class': 'passerelle.utils.jsonresponse.APIError', + 'data': {'content': {'foo': 'bar'}, 'status_code': 400}, + 'err_desc': 'Esabora platform "http://example.esabora/ws/rest/" answered with HTTP error', + } + + response = app.post_json(url, params=payload) + assert response.json == expected_response