Skip to content

Commit e059017

Browse files
Handle TooManyRequests exception gracefully
1 parent 448e56e commit e059017

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

lambdas/services/virus_scan_result_service.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,16 @@ def get_new_access_token(self):
114114
)
115115

116116
response.raise_for_status()
117-
new_access_token = response.json()["accessToken"]
117+
self.access_token = response.json()["accessToken"]
118118

119-
self.update_ssm_access_token(new_access_token)
120-
self.access_token = new_access_token
121-
except (HTTPError, KeyError, TypeError) as e:
119+
self.update_ssm_access_token(self.access_token)
120+
except Exception as e:
121+
# ignore TooManyRequests exception as it will be handled by the retry mechanism in request_virus_scan
122+
# this is to prevent a scenario where multiple concurrent Lambda executions all attempt to refresh the token at the same time,
123+
# resulting in a flood of requests to the token endpoint and subsequent failures. By ignoring the TooManyRequests exception,
124+
# we allow the retry mechanism to handle the situation gracefully without overwhelming the token service.
125+
if str(e).find("TooManyRequests") != -1:
126+
return
122127
logger.error(
123128
f"{LambdaError.VirusScanNoToken.to_str()}: {str(e)}",
124129
{"Result": FAIL_SCAN},

lambdas/tests/unit/services/test_virus_scan_result_service.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,30 @@ def test_scan_file_when_parameters_are_set(
328328

329329
virus_scanner_service.get_ssm_parameters_for_request_access_token.assert_not_called()
330330
mock_request_virus_scan.assert_called_once()
331+
332+
def test_get_new_access_token_handles_TooManyRequests_exception(mocker, virus_scanner_service):
333+
response = Response()
334+
response.status_code = 200
335+
response._content = json.dumps(RESPONSE_TOKEN).encode("utf-8")
336+
virus_scanner_service.base_url = "test.endpoint"
337+
virus_scanner_service.username = "test_username"
338+
virus_scanner_service.password = "test_password"
339+
mock_post = mocker.patch("requests.post", return_value=response)
340+
341+
excepted_token_url = virus_scanner_service.base_url + "/api/Token"
342+
excepted_json_data_request = {
343+
"username": virus_scanner_service.username,
344+
"password": virus_scanner_service.password,
345+
}
346+
347+
virus_scanner_service.get_new_access_token()
348+
349+
virus_scanner_service.update_ssm_access_token = mocker.MagicMock(side_effect=Exception("TooManyRequests"))
350+
351+
assert virus_scanner_service.access_token == RESPONSE_TOKEN["accessToken"]
352+
353+
mock_post.assert_called_with(
354+
url=excepted_token_url,
355+
headers={"Content-type": "application/json"},
356+
data=json.dumps(excepted_json_data_request),
357+
)

0 commit comments

Comments
 (0)