Fix block_structure error handling BOM-577 (#21801)

This commit is contained in:
Jeremy Bowman
2019-09-27 10:06:00 -04:00
committed by GitHub
parent a91fcfceed
commit 88b8e97409
2 changed files with 17 additions and 9 deletions

View File

@@ -4,6 +4,7 @@ Models used by the block structure framework.
from __future__ import absolute_import
import errno
from contextlib import contextmanager
from datetime import datetime
from logging import getLogger
@@ -117,7 +118,9 @@ def _storage_error_handling(bs_model, operation, is_read_operation=False):
yield
except Exception as error: # pylint: disable=broad-except
log.exception(u'BlockStructure: Exception %s on store %s; %s.', error.__class__, operation, bs_model)
if is_read_operation and isinstance(error, (IOError, SuspiciousOperation)):
if isinstance(error, OSError) and error.errno in (errno.EACCES, errno.EPERM): # pylint: disable=no-member
raise
elif is_read_operation and isinstance(error, (IOError, SuspiciousOperation)):
# May have been caused by one of the possible error
# situations listed above. Raise BlockStructureNotFound
# so the block structure can be regenerated and restored.

View File

@@ -4,6 +4,7 @@ Unit tests for Block Structure models.
# pylint: disable=protected-access
from __future__ import absolute_import
import errno
from itertools import product
from uuid import uuid4
@@ -147,19 +148,23 @@ class BlockStructureModelTestCase(TestCase):
self._assert_file_count_equal(min(num_prior_edits + 1, prune_keep_count))
@ddt.data(
(IOError, BlockStructureNotFound, True),
(IOError, IOError, False),
(SuspiciousOperation, BlockStructureNotFound, True),
(SuspiciousOperation, SuspiciousOperation, False),
(OSError, OSError, True),
(OSError, OSError, False),
(IOError, errno.ENOENT, u'No such file or directory', BlockStructureNotFound, True),
(IOError, errno.ENOENT, u'No such file or directory', IOError, False),
(SuspiciousOperation, None, None, BlockStructureNotFound, True),
(SuspiciousOperation, None, None, SuspiciousOperation, False),
(OSError, errno.EACCES, u'Permission denied', OSError, True),
(OSError, errno.EACCES, u'Permission denied', OSError, False),
)
@ddt.unpack
def test_error_handling(self, error_raised_in_operation, expected_error_raised, is_read_operation):
def test_error_handling(self, error_raised_in_operation, errno_raised, message_raised,
expected_error_raised, is_read_operation):
bs_model, _ = BlockStructureModel.update_or_create('test data', **self.params)
with self.assertRaises(expected_error_raised):
with _storage_error_handling(bs_model, 'operation', is_read_operation):
raise error_raised_in_operation
if errno_raised is not None:
raise error_raised_in_operation(errno_raised, message_raised)
else:
raise error_raised_in_operation
@patch('openedx.core.djangoapps.content.block_structure.models.log')
def test_old_mongo_keys(self, mock_log):