Skip to content

Commit 1246868

Browse files
fix(exception-handling): Catch errors when requesting datafile (#285)
1 parent 3e0fa0a commit 1246868

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

optimizely/config_manager.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ def _handle_response(self, response):
325325
"""
326326
try:
327327
response.raise_for_status()
328-
except requests_exceptions.HTTPError as err:
328+
except requests_exceptions.RequestException as err:
329329
self.logger.error('Fetching datafile from {} failed. Error: {}'.format(self.datafile_url, str(err)))
330330
return
331331

tests/test_config_manager.py

+41
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,47 @@ def test_fetch_datafile(self, _):
392392
)
393393
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
394394
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
395+
self.assertTrue(project_config_manager.is_running)
396+
397+
def test_fetch_datafile__exception_raised(self, _):
398+
""" Test that config_manager keeps running if exception is raised when fetching datafile. """
399+
class MockExceptionResponse(object):
400+
def raise_for_status(self):
401+
raise requests.exceptions.RequestException('Error Error !!')
402+
403+
sdk_key = 'some_key'
404+
mock_logger = mock.Mock()
405+
with mock.patch('optimizely.config_manager.PollingConfigManager.fetch_datafile'):
406+
project_config_manager = config_manager.PollingConfigManager(sdk_key=sdk_key, logger=mock_logger)
407+
expected_datafile_url = enums.ConfigManager.DATAFILE_URL_TEMPLATE.format(sdk_key=sdk_key)
408+
test_headers = {'Last-Modified': 'New Time'}
409+
test_datafile = json.dumps(self.config_dict_with_features)
410+
test_response = requests.Response()
411+
test_response.status_code = 200
412+
test_response.headers = test_headers
413+
test_response._content = test_datafile
414+
with mock.patch('requests.get', return_value=test_response):
415+
project_config_manager.fetch_datafile()
416+
417+
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
418+
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
419+
420+
# Call fetch_datafile again, but raise exception this time
421+
with mock.patch('requests.get', return_value=MockExceptionResponse()) as mock_requests:
422+
project_config_manager.fetch_datafile()
423+
424+
mock_requests.assert_called_once_with(
425+
expected_datafile_url,
426+
headers={'If-Modified-Since': test_headers['Last-Modified']},
427+
timeout=enums.ConfigManager.REQUEST_TIMEOUT,
428+
)
429+
mock_logger.error.assert_called_once_with('Fetching datafile from {} failed. Error: Error Error !!'.format(
430+
expected_datafile_url
431+
))
432+
self.assertEqual(test_headers['Last-Modified'], project_config_manager.last_modified)
433+
self.assertIsInstance(project_config_manager.get_config(), project_config.ProjectConfig)
434+
# Confirm that config manager keeps running
435+
self.assertTrue(project_config_manager.is_running)
395436

396437
def test_is_running(self, _):
397438
""" Test that polling thread is running after instance of PollingConfigManager is created. """

0 commit comments

Comments
 (0)