From 71429c9250a97500cbf8dfc460ca2800e40e670e Mon Sep 17 00:00:00 2001 From: Florent VIEL Date: Thu, 24 Sep 2026 11:08:04 +0200 Subject: [PATCH 1/2] fix: catch json decode error first --- scaleway-core/scaleway_core/api.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scaleway-core/scaleway_core/api.py b/scaleway-core/scaleway_core/api.py index 81c8012b9..83e907cb9 100644 --- a/scaleway-core/scaleway_core/api.py +++ b/scaleway-core/scaleway_core/api.py @@ -186,7 +186,11 @@ def _request( def _throw_on_error(self, res: requests.Response) -> None: if res.status_code is not None and res.status_code >= 400: - data = res.json() + data = None + try: + data = res.json() + except requests.exceptions.JSONDecodeError: + pass if data: if "message" in data: From 03d3934242b5550a785ff8a6712874b3a8764361 Mon Sep 17 00:00:00 2001 From: Florent VIEL Date: Thu, 24 Sep 2026 11:08:42 +0200 Subject: [PATCH 2/2] feat: add test to validate json decode error catched --- scaleway-core/tests/test_api.py | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 scaleway-core/tests/test_api.py diff --git a/scaleway-core/tests/test_api.py b/scaleway-core/tests/test_api.py new file mode 100644 index 000000000..b95781ad3 --- /dev/null +++ b/scaleway-core/tests/test_api.py @@ -0,0 +1,50 @@ +import unittest +import uuid + +from requests.models import Response + +from scaleway_core.api import API, ScalewayException, ValidationError +from scaleway_core.client import Client + + +def _response(status_code: int, body: bytes) -> Response: + response = Response() + response.status_code = status_code + response._content = body + return response + + +def _api() -> API: + client = Client( + access_key="SCW" + "A" * 17, + secret_key=str(uuid.uuid4()), + ) + return API(client) + + +class TestThrowOnError(unittest.TestCase): + def test_non_json_error_raises_scaleway_exception_with_raw_body(self): + response = _response(502, b"Bad Gateway") + + with self.assertRaises(ScalewayException) as context: + _api()._throw_on_error(response) + + self.assertEqual(context.exception.status_code, 502) + self.assertIn("Bad Gateway", str(context.exception)) + + def test_json_error_raises_scaleway_exception(self): + response = _response(500, b'{"message": "boom"}') + + with self.assertRaises(ScalewayException): + _api()._throw_on_error(response) + + def test_validation_error_raises_validation_error(self): + response = _response( + 400, + b'{"message": "Validation Error", "fields": {"name": "required"}}', + ) + + with self.assertRaises(ValidationError) as context: + _api()._throw_on_error(response) + + self.assertEqual(context.exception.errors, {"name": "required"})