Fix block_structure error handling BOM-577 (#21801)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user