From 670477e7d5b38ea572f3cd540c77a5a862947a70 Mon Sep 17 00:00:00 2001 From: Nathan Sprenkle Date: Wed, 18 Jan 2023 11:40:38 -0500 Subject: [PATCH] fix: add fallthrough exception for course overview (#31582) An issue trying to get a course overview for a deleted course and trying to write back into the DB had been raising unhandled errors. Catching other classes of errors to keep this function from breaking. Should just return None in these cases and log the exception. --- .../core/djangoapps/content/course_overviews/api.py | 7 ++++++- .../content/course_overviews/tests/test_api.py | 10 ++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/openedx/core/djangoapps/content/course_overviews/api.py b/openedx/core/djangoapps/content/course_overviews/api.py index fcad69c7e0..972469f83a 100644 --- a/openedx/core/djangoapps/content/course_overviews/api.py +++ b/openedx/core/djangoapps/content/course_overviews/api.py @@ -24,7 +24,12 @@ def get_course_overview_or_none(course_id): return CourseOverview.get_from_id(course_id) except CourseOverview.DoesNotExist: log.warning(f"Course overview does not exist for {course_id}") - return None + except Exception as ex: # pylint: disable=broad-except + # NOTE - Included because some cases (e.g. deleted courses) can throw other + # types of errors due to with the cache (see APER-2171 and AU-1000). + log.exception(f"Unhandled exception getting course overview for {course_id}: {ex}") + + return None def get_course_overview_or_404(course_id): diff --git a/openedx/core/djangoapps/content/course_overviews/tests/test_api.py b/openedx/core/djangoapps/content/course_overviews/tests/test_api.py index 6c04e4a47c..d98c6f0d01 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests/test_api.py +++ b/openedx/core/djangoapps/content/course_overviews/tests/test_api.py @@ -45,6 +45,16 @@ class TestCourseOverviewsApi(ModuleStoreTestCase): retrieved_course_overview = get_course_overview_or_none(course_run_key) assert retrieved_course_overview is None + @patch('openedx.core.djangoapps.content.course_overviews.api.CourseOverview.get_from_id') + def test_get_course_overview_or_none_exception(self, mock_get): + """ + Test for `get_course_overview_or_none` function when an exception is raised. + """ + course_run_key = CourseKey.from_string('course-v1:coping+with+exceptions') + mock_get.side_effect = Exception() + retrieved_course_overview = get_course_overview_or_none(course_run_key) + assert retrieved_course_overview is None + def test_get_course_overview_or_404_success(self): """ Test for `test_get_course_overview_or_404` function when the overview exists.