Skip to content

Commit 93a4731

Browse files
authored
Fix #718 by handling unexpected response body format (#751)
1 parent c1c419f commit 93a4731

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

slack/web/base_client.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ async def _request(self, *, http_verb, api_url, req_args):
303303
self._logger.debug(
304304
f"No response data returned from the following API call: {api_url}."
305305
)
306+
except json.decoder.JSONDecodeError as e:
307+
message = f"Failed to parse the response body: {str(e)}"
308+
raise err.SlackApiError(message, res)
309+
306310
response = {
307311
"data": data,
308312
"headers": res.headers,
@@ -456,7 +460,11 @@ def convert_params(values: dict) -> dict:
456460

457461
response = self._perform_urllib_http_request(url=url, args=request_args)
458462
if response.get("body", None):
459-
response_body_data: dict = json.loads(response["body"])
463+
try:
464+
response_body_data: dict = json.loads(response["body"])
465+
except json.decoder.JSONDecodeError as e:
466+
message = f"Failed to parse the response body: {str(e)}"
467+
raise err.SlackApiError(message, response)
460468
else:
461469
response_body_data: dict = None
462470

tests/web/mock_web_api_server.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class MockHandler(SimpleHTTPRequestHandler):
1818
pattern_for_language = re.compile("python/(\\S+)", re.IGNORECASE)
1919
pattern_for_package_identifier = re.compile("slackclient/(\\S+)")
2020

21+
html_response_body = '<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>404 Not Found</title>\n</head><body>\n<h1>Not Found</h1>\n<p>The requested URL /api/team.info was not found on this server.</p>\n</body></html>\n'
22+
2123
def is_valid_user_agent(self):
2224
user_agent = self.headers["User-Agent"]
2325
return self.pattern_for_language.search(user_agent) \
@@ -98,6 +100,13 @@ def _handle(self):
98100
self.wfile.close()
99101
return
100102

103+
if pattern == "html_response":
104+
self.send_response(404)
105+
self.set_common_headers()
106+
self.wfile.write(self.html_response_body.encode("utf-8"))
107+
self.wfile.close()
108+
return
109+
101110
if request_body and "cursor" in request_body:
102111
page = request_body["cursor"]
103112
pattern = f"{pattern}_{page}"

tests/web/test_web_client.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,4 +243,23 @@ async def issue_645():
243243
loop.set_exception_handler(exception_handler)
244244
loop.run_until_complete(issue_645())
245245
gc.collect() # force Python to gc unclosed client session
246-
self.assertFalse(session_unclosed, "Unclosed client session")
246+
self.assertFalse(session_unclosed, "Unclosed client session")
247+
248+
def test_html_response_body_issue_718(self):
249+
client = WebClient(base_url="http://localhost:8888")
250+
try:
251+
client.users_list(token="xoxb-html_response")
252+
self.fail("SlackApiError expected here")
253+
except err.SlackApiError as e:
254+
self.assertTrue(
255+
str(e).startswith("Failed to parse the response body: Expecting value: line 1 column 1 (char 0)"), e)
256+
257+
@async_test
258+
async def test_html_response_body_issue_718_async(self):
259+
client = WebClient(base_url="http://localhost:8888", run_async=True)
260+
try:
261+
await client.users_list(token="xoxb-html_response")
262+
self.fail("SlackApiError expected here")
263+
except err.SlackApiError as e:
264+
self.assertTrue(
265+
str(e).startswith("Failed to parse the response body: Expecting value: line 1 column 1 (char 0)"), e)

0 commit comments

Comments
 (0)