Commit ace2bffa by jsa

avoid database error when recording task exception

parent 0f0b2cbd
...@@ -1721,6 +1721,26 @@ class RerunCourseTest(ContentStoreTestCase): ...@@ -1721,6 +1721,26 @@ class RerunCourseTest(ContentStoreTestCase):
self.assertEquals(rerun_state.state, CourseRerunUIStateManager.State.FAILED) self.assertEquals(rerun_state.state, CourseRerunUIStateManager.State.FAILED)
self.assertIn(error_message, rerun_state.message) self.assertIn(error_message, rerun_state.message)
def test_rerun_error_trunc_message(self):
"""
CourseActionUIState.message is sometimes populated with the contents
of Python tracebacks. This test ensures we don't crash when attempting
to insert a value exceeding its max_length (note that sqlite does not
complain if this happens, but MySQL throws an error).
"""
with mock.patch(
'xmodule.modulestore.mixed.MixedModuleStore.clone_course',
mock.Mock(side_effect=Exception()),
):
source_course = CourseFactory.create()
message_too_long = "traceback".rjust(CourseRerunState.MAX_MESSAGE_LENGTH * 2, '-')
with mock.patch('traceback.format_exc', return_value=message_too_long):
destination_course_key = self.post_rerun_request(source_course.id)
rerun_state = CourseRerunState.objects.find_first(course_key=destination_course_key)
self.assertEquals(rerun_state.state, CourseRerunUIStateManager.State.FAILED)
self.assertTrue(rerun_state.message.endswith("traceback"))
self.assertEqual(len(rerun_state.message), CourseRerunState.MAX_MESSAGE_LENGTH)
class EntryPageTestCase(TestCase): class EntryPageTestCase(TestCase):
""" """
......
...@@ -143,7 +143,7 @@ class CourseRerunUIStateManager(CourseActionUIStateManager): ...@@ -143,7 +143,7 @@ class CourseRerunUIStateManager(CourseActionUIStateManager):
self.update_state( self.update_state(
course_key=course_key, course_key=course_key,
new_state=self.State.FAILED, new_state=self.State.FAILED,
message=traceback.format_exc(), message=traceback.format_exc()[-self.model.MAX_MESSAGE_LENGTH:], # truncate to fit
) )
......
...@@ -83,13 +83,17 @@ class CourseActionUIState(CourseActionState): ...@@ -83,13 +83,17 @@ class CourseActionUIState(CourseActionState):
""" """
abstract = True abstract = True
# WARNING - when you edit this value, you're also modifying the max_length
# of the `message` column (see below)
MAX_MESSAGE_LENGTH = 1000
# FIELDS # FIELDS
# Whether or not the status should be displayed to users # Whether or not the status should be displayed to users
should_display = models.BooleanField() should_display = models.BooleanField()
# Message related to the status # Message related to the status
message = models.CharField(max_length=1000) message = models.CharField(max_length=MAX_MESSAGE_LENGTH)
# Rerun courses also need these fields. All rerun course actions will have a row here as well. # Rerun courses also need these fields. All rerun course actions will have a row here as well.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment