diff --git a/gazu/client.py b/gazu/client.py index bb0275e4..b4e0f867 100644 --- a/gazu/client.py +++ b/gazu/client.py @@ -303,6 +303,30 @@ def delete(path, params=None, client=default_client): return response.text +def get_message_from_response(response: requests.Request, default_message: str = "No additional information") -> str: + """ + A utility function that handles Zou's inconsistent message keys. + For a given request, checks if any error messages or regular messages were given and returns their value. + If no messages are found, returns a default message. + + Args: + response: requests.Request - A response to check. + default_message: str - An optional default value to revert to if no message is detected. + + Returns: + The message of a given response, or a default message - if any. + """ + message = default_message + message_json = response.json() + + for key in ['error', 'message']: + if message_json.get(key): + message = message_json[key] + break + + return message + + def check_status(request, path, client=None): """ Raise an exception related to status code, if the status code does not @@ -329,8 +353,7 @@ def check_status(request, path, client=None): elif status_code == 403: raise NotAllowedException(path) elif status_code == 400: - text = request.json().get("message", "No additional information") - raise ParameterException(path, text) + raise ParameterException(path, get_message_from_response(request)) elif status_code == 405: raise MethodNotAllowedException(path) elif status_code == 413: @@ -362,9 +385,8 @@ def check_status(request, path, client=None): stacktrace = request.json().get( "stacktrace", "No stacktrace sent by the server" ) - message = request.json().get( - "message", "No message sent by the server" - ) + message = get_message_from_response(response=request, + default_message="No message sent by the server") print("A server error occured!\n") print("Server stacktrace:\n%s" % stacktrace) print("Error message:\n%s\n" % message) @@ -474,8 +496,11 @@ def upload(path, file_path, data={}, extra_files=[], client=default_client): except JSONDecodeError: print(response.text) raise - if "message" in result: - raise UploadFailedException(result["message"]) + + result_message = get_message_from_response(response, default_message='') + if result_message: + raise UploadFailedException(result_message) + return result diff --git a/tests/test_client.py b/tests/test_client.py index 5fdb6a9a..128f7ff4 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,5 +1,7 @@ import datetime import json +import random +import string import unittest import requests_mock @@ -281,19 +283,24 @@ def test_upload(self): "./tests/fixtures/v1.png", data={"test": True}, ) + + error_value = ''.join([random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in range(10)]) + with requests_mock.Mocker() as mock: - mock_route( - mock, - "POST", - "data/new-file", - text={"message": "Error"}, - ) - with self.assertRaises(gazu.client.UploadFailedException): - raw.upload( + for field in ['message', 'error']: + mock_route( + mock, + "POST", "data/new-file", - "./tests/fixtures/v1.png", - data={"test": True}, - ) + text={field: error_value}) + + with self.assertRaises(gazu.client.UploadFailedException) as context: + raw.upload( + "data/new-file", + "./tests/fixtures/v1.png", + data={"test": True}) + + self.assertTrue(str(context.exception) == error_value) def test_upload_multiple_files(self): with open("./tests/fixtures/v1.png", "rb") as test_file: diff --git a/tests/test_files.py b/tests/test_files.py index 6319db21..bb44fbec 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -39,6 +39,16 @@ def test_new_working_file(self): ) self.assertEqual(working_file["id"], 1) + mock.post(gazu.client.get_full_url(path), + text=json.dumps({"error": "The given working file already exists."}), + status_code=400) + + with self.assertRaises(gazu.client.ParameterException) as context: + gazu.files.new_working_file( + task, person={"id": "person-01"}, software={"id": "software-1"}) + + self.assertTrue(str(context.exception) == "The given working file already exists.") + def test_new_entity_output_file(self): entity = {"id": "asset-01"} output_type = {"id": "output-type-01"}