diff --git a/exoscale/api/exceptions.py b/exoscale/api/exceptions.py index 569b643..67ad778 100644 --- a/exoscale/api/exceptions.py +++ b/exoscale/api/exceptions.py @@ -34,4 +34,4 @@ class ExoscaleAPIAuthException(ExoscaleAPIException): Shows the server encountered an error while processing the request. """ - pass \ No newline at end of file + pass diff --git a/exoscale/api/v2.py b/exoscale/api/v2.py index 3983afa..4b6ddcd 100644 --- a/exoscale/api/v2.py +++ b/exoscale/api/v2.py @@ -27,7 +27,11 @@ from pathlib import Path from exoscale_auth import ExoscaleV2Auth -from .exceptions import ExoscaleAPIAuthException, ExoscaleAPIClientException, ExoscaleAPIServerException +from .exceptions import ( + ExoscaleAPIAuthException, + ExoscaleAPIClientException, + ExoscaleAPIServerException, +) import requests @@ -158,7 +162,7 @@ def _call_operation(self, operation_id, parameters=None, body=None): ) # Error handling - if response.status_code == 403 : + if response.status_code == 403: raise ExoscaleAPIAuthException( f"Authentication error {response.status_code}: {response.text}" ) diff --git a/tests/test_client.py b/tests/test_client.py index 9e10cb5..bdd0d9c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -2,6 +2,12 @@ from exoscale.api.v2 import Client +from exoscale.api.exceptions import ( + ExoscaleAPIClientException, + ExoscaleAPIServerException, + ExoscaleAPIAuthException, +) + def test_client_creation(): c = Client("key", "secret", zone="at-vie-1") @@ -20,3 +26,54 @@ def test_client_creation(): # create with custom URL c = Client("key", "secret", url="http://localhost:8000/v2") assert hasattr(c, "list_zones") + + +def test_client_error_handling(requests_mock): + client = Client(key="EXOtest", secret="sdsd") + + # Mock a 403 authentication error + requests_mock.get( + "https://api-ch-gva-2.exoscale.com/v2/instance/85664334-0fd5-47bd-94a1-b4f40b1d2eb7", + status_code=403, + text='{"message":"Invalid request signature"}', + ) + try: + client_with_wrong_key = Client(key="EXOtest", secret="wrong_secret") + client_with_wrong_key.get_instance( + id="85664334-0fd5-47bd-94a1-b4f40b1d2eb7" + ) + except ExoscaleAPIAuthException as e: + assert "Authentication error 403" in str(e) + assert '{"message":"Invalid request signature"}' in str(e) + + # Mock a 404 client error + requests_mock.get( + "https://api-ch-gva-2.exoscale.com/v2/instance/85664334-0fd5-47bd-94a1-b4f40b1d2eb7", + status_code=404, + text='{"message":"Instance not found"}', + ) + try: + client.get_instance(id="85664334-0fd5-47bd-94a1-b4f40b1d2eb7") + except ExoscaleAPIClientException as e: + assert "Client error 404" in str(e) + assert '{"message":"Instance not found"}' in str(e) + + # Mock a 500 server error + requests_mock.get( + "https://api-ch-gva-2.exoscale.com/v2/500_error", + status_code=500, + text="Internal Server Error", + ) + try: + response = client.session.get( + "https://api-ch-gva-2.exoscale.com/v2/500_error" + ) + response.raise_for_status() + except ExoscaleAPIServerException as e: + assert "Server error 500" in str(e) + except Exception as e: + assert "500 Server Error" in str(e) + + +if __name__ == "__main__": + pytest.main()