Skip to content

Commit d6249c1

Browse files
authored
Merge pull request #20 from imagekit-developer/patch/json-parsing-error-handling
IMAGEKIT-132: JSON parsing error handling when server returns string
2 parents 3856524 + 8d5196c commit d6249c1

File tree

6 files changed

+53
-5
lines changed

6 files changed

+53
-5
lines changed

.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ omit =
33
*/site-packages/*
44
*/distutils/*
55
tests/*
6+
.tox/*

.github/workflows/test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ jobs:
1919
run: pip install -r requirements/test.txt
2020
- name: Run Tox
2121
run: tox -e py
22+
- name: Upload Coverage to codecov
23+
run: bash <(curl -s https://codecov.io/bash)

imagekitio/file.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import json
1+
from json import dumps
22
from typing import Any, Dict
33

44
from .constants.errors import ERRORS
@@ -10,6 +10,10 @@
1010
snake_to_lower_camel,
1111
)
1212

13+
try:
14+
from simplejson.errors import JSONDecodeError
15+
except ImportError:
16+
from json import JSONDecodeError
1317

1418
class File(object):
1519
def __init__(self, request_obj):
@@ -47,7 +51,10 @@ def upload(self, file, file_name, options) -> Dict:
4751
)
4852

4953
if resp.status_code > 200:
50-
error = resp.json()
54+
try:
55+
error = resp.json()
56+
except JSONDecodeError:
57+
error = resp.text
5158
response = None
5259
else:
5360
error = None
@@ -107,7 +114,7 @@ def update_file_details(self, file_id: str, options: dict):
107114
url = "{}/{}/details/".format(URL.BASE_URL.value, file_id)
108115
headers = {"Content-Type": "application/json"}
109116
headers.update(self.request.get_auth_headers())
110-
data = json.dumps(request_formatter(options))
117+
data = dumps(request_formatter(options))
111118
resp = self.request.request(method="Patch", url=url, headers=headers, data=data)
112119
if resp.status_code > 200:
113120
error = resp.json()
@@ -171,7 +178,7 @@ def purge_cache(self, file_url: str = None) -> Dict[str, Any]:
171178
headers.update(self.request.get_auth_headers())
172179
body = {"url": file_url}
173180
resp = self.request.request(
174-
"Post", headers=headers, url=url, data=json.dumps(body)
181+
"Post", headers=headers, url=url, data=dumps(body)
175182
)
176183
formatted_resp = camel_dict_to_snake_dict(resp.json())
177184
if resp.status_code > 204:

tests/helpers.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
from imagekitio.client import ImageKit
88
from tests.dummy_data.file import AUTHENTICATION_ERR_MSG, SUCCESS_GENERIC_RESP
9+
try:
10+
from simplejson.errors import JSONDecodeError
11+
except ImportError:
12+
from json import JSONDecodeError
913

1014

1115
class ClientTestCase(unittest.TestCase):
@@ -41,6 +45,16 @@ def get_mocked_failed_resp(message=None, status=401):
4145
return mocked_resp
4246

4347

48+
def get_mocked_failed_resp_text():
49+
"""GET failed mocked response returned as text not json
50+
"""
51+
mocked_resp = Mock(spec=Response)
52+
mocked_resp.status_code = 502
53+
mocked_resp.text = 'Bad Gateway'
54+
mocked_resp.json.side_effect = JSONDecodeError("Expecting value: ", "Bad Gateway", 0)
55+
return mocked_resp
56+
57+
4458
def get_mocked_success_resp(message: dict = None, status: int = 200):
4559
"""GET success mocked response customize by parameter
4660
"""

tests/test_files_ops.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from tests.helpers import (
1616
ClientTestCase,
1717
get_mocked_failed_resp,
18+
get_mocked_failed_resp_text,
1819
get_mocked_success_resp,
1920
)
2021
from imagekitio.utils.formatter import request_formatter
@@ -173,6 +174,27 @@ def test_upload_file_fails_without_file_or_file_name(self) -> None:
173174
self.assertRaises(TypeError, self.client.upload_file, file_name=self.filename)
174175
self.assertRaises(TypeError, self.client.upload_file, file=self.image)
175176

177+
def test_upload_file_fails_without_json_response_from_server(self) -> None:
178+
"""Test upload raises error on non json response
179+
"""
180+
self.client.ik_request.request = MagicMock(
181+
return_value=get_mocked_failed_resp_text()
182+
)
183+
resp = self.client.upload(
184+
file=self.image,
185+
file_name="fileabc",
186+
options={
187+
"is_private_file": True,
188+
"tags": ["abc"],
189+
"response_fields": ["is_private_file", "tags"],
190+
"custom_coordinates": "10,10,100,100",
191+
"use_unique_file_name": True,
192+
"folder": "abc"
193+
}
194+
)
195+
self.assertIsNotNone(resp["error"])
196+
self.assertIsNone(resp["response"])
197+
176198

177199
class TestListFiles(ClientTestCase):
178200
"""

tox.ini

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@ skipsdist = True
55
[testenv]
66
passenv = *
77
deps = -rrequirements/test.txt
8-
commands = python -m unittest discover tests
8+
commands =
9+
coverage run --append -m unittest discover tests
10+
coverage report

0 commit comments

Comments
 (0)