From 48e9724808fa7683518ccfd5d8cf89522e6bf5da Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 5 Dec 2019 17:03:26 -0500 Subject: [PATCH] Handle other places where we might be unpickling things. We use pickling in conjunction with caches in these cases so we should be able to fallback to the uncached behavior if the pickled data is corrupt in some way. eg. it's a python 2 pickle we don't know how to read. --- .../djangoapps/content/block_structure/store.py | 10 +++++++++- openedx/core/lib/edx_api_utils.py | 13 +++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/openedx/core/djangoapps/content/block_structure/store.py b/openedx/core/djangoapps/content/block_structure/store.py index c6568f031f..aa4d90d481 100644 --- a/openedx/core/djangoapps/content/block_structure/store.py +++ b/openedx/core/djangoapps/content/block_structure/store.py @@ -207,7 +207,15 @@ class BlockStructureStore(object): """ Deserializes the given data and returns the parsed block_structure. """ - block_relations, transformer_data, block_data_map = zunpickle(serialized_data) + + try: + block_relations, transformer_data, block_data_map = zunpickle(serialized_data) + except Exception: + # Somehow failed to de-serialized the data, assume it's corrupt. + bs_model = self._get_model(root_block_usage_key) + logger.warning("BlockStructure: Failed to load data from cache for %s", bs_model) + raise BlockStructureNotFound(bs_model.data_usage_key) + return BlockStructureFactory.create_new( root_block_usage_key, block_relations, diff --git a/openedx/core/lib/edx_api_utils.py b/openedx/core/lib/edx_api_utils.py index 0f1fab26a1..e927dbaf5d 100644 --- a/openedx/core/lib/edx_api_utils.py +++ b/openedx/core/lib/edx_api_utils.py @@ -56,11 +56,16 @@ def get_edx_api_data(api_config, resource, api, resource_id=None, querystring=No cached = cache.get(cache_key) if cached: - cached_response = zunpickle(cached) - if fields: - cached_response = get_fields(fields, cached_response) + try: + cached_response = zunpickle(cached) + if fields: + cached_response = get_fields(fields, cached_response) - return cached_response + return cached_response + except Exception: + # Data is corrupt in some way. + log.warning("Data for cache is corrupt for cache key %s", cache_key) + cache.delete(cache_key) try: endpoint = getattr(api, resource)