From 1a02cfec8350dd8bc98beeef70aaa632ea9b2021 Mon Sep 17 00:00:00 2001
From: kimth
Date: Sat, 15 Sep 2012 23:25:26 -0400
Subject: [PATCH 1/6] Reset CapaProblem when state HTML is corrupt
---
common/lib/xmodule/xmodule/capa_module.py | 36 ++++++++++++++++++-----
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 8bf1a56404..a344d2981d 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -131,17 +131,17 @@ class CapaModule(XModule):
self.weight = None
if self.rerandomize == 'never':
- seed = 1
+ self.seed = 1
elif self.rerandomize == "per_student" and hasattr(self.system, 'id'):
- seed = system.id
+ self.seed = system.id
else:
- seed = None
+ self.seed = None
try:
# TODO (vshnayder): move as much as possible of this work and error
# checking to descriptor load time
self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(),
- instance_state, seed=seed, system=self.system)
+ instance_state, seed=self.seed, system=self.system)
except Exception as err:
msg = 'cannot create LoncapaProblem {loc}: {err}'.format(
loc=self.location.url(), err=err)
@@ -160,7 +160,7 @@ class CapaModule(XModule):
(self.location.url(), msg))
self.lcp = LoncapaProblem(
problem_text, self.location.html_id(),
- instance_state, seed=seed, system=self.system)
+ instance_state, seed=self.seed, system=self.system)
else:
# add extra info and raise
raise Exception(msg), None, sys.exc_info()[2]
@@ -220,9 +220,10 @@ class CapaModule(XModule):
try:
html = self.lcp.get_html()
except Exception, err:
+ log.exception(err)
+
# TODO (vshnayder): another switch on DEBUG.
if self.system.DEBUG:
- log.exception(err)
msg = (
'[courseware.capa.capa_module] '
'Failed to generate HTML for problem %s' %
@@ -231,7 +232,28 @@ class CapaModule(XModule):
msg += '%s
' % traceback.format_exc().replace('<', '<')
html = msg
else:
- raise
+ # We're in non-debug mode, and possibly even in production. We want
+ # to avoid bricking of problem as much as possible
+
+ # Presumably, student submission has corrupted LoncapaProblem HTML.
+ # So, let's try generate a fresh LoncapaProblem
+ self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(),
+ state=None, # Tabula rasa
+ seed=self.seed, system=self.system)
+
+ # Prepend a scary warning to the student
+ warning = ''
+ warning += '
Problem state was corruped by invalid input. '
+ warning += 'Problem reset to initial state! '
+ warning += 'If problem persists, please contact the course staff.
'
+ warning += '
'
+
+ html = warning
+ try:
+ html += self.lcp.get_html()
+ except Exception, err: # Couldn't do it. Give up
+ log.exception(err)
+ raise
content = {'name': self.display_name,
'html': html,
From 827e211ac75f59ff0c19373f6b31cde06e2f55c2 Mon Sep 17 00:00:00 2001
From: kimth
Date: Sun, 16 Sep 2012 00:27:41 -0400
Subject: [PATCH 2/6] Reveal student input at state of problem reset back to
student
---
common/lib/xmodule/xmodule/capa_module.py | 26 +++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index a344d2981d..894d23c342 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -1,3 +1,4 @@
+import cgi
import datetime
import dateutil
import dateutil.parser
@@ -236,16 +237,33 @@ class CapaModule(XModule):
# to avoid bricking of problem as much as possible
# Presumably, student submission has corrupted LoncapaProblem HTML.
- # So, let's try generate a fresh LoncapaProblem
+ # First, pull down all student answers
+ student_answers = self.lcp.student_answers
+ answer_ids = student_answers.keys()
+
+ # Some inputtypes, such as dynamath, have additional "hidden" state that
+ # is not exposed to the student. Keep those hidden
+ hidden_state_keywords = ['dynamath']
+ for answer_id in answer_ids:
+ for hidden_state_keyword in hidden_state_keywords:
+ if answer_id.find(hidden_state_keyword) >= 0:
+ student_answers.pop(answer_id)
+
+ # Next, generate a fresh LoncapaProblem
self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(),
state=None, # Tabula rasa
seed=self.seed, system=self.system)
# Prepend a scary warning to the student
warning = ''
- warning += '
Problem state was corruped by invalid input. '
- warning += 'Problem reset to initial state! '
- warning += 'If problem persists, please contact the course staff.
'
+ warning += '
Problem reset to initial state!
'
+ warning += '
Problem state was corruped by invalid submission. The submission consisted of:
'
+ warning += '
'
+ for student_answer in student_answers.values():
+ if student_answer != '':
+ warning += '- ' + cgi.escape(student_answer) + '
'
+ warning += '
'
+ warning += '
If problem persists, please contact the course staff.
'
warning += '
'
html = warning
From eac8037808c8c480ce3c34d6e39df06e21c2acdf Mon Sep 17 00:00:00 2001
From: kimth
Date: Sun, 16 Sep 2012 00:29:48 -0400
Subject: [PATCH 3/6] Add TODO comment
---
common/lib/xmodule/xmodule/capa_module.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 894d23c342..9eeaa57896 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -243,6 +243,7 @@ class CapaModule(XModule):
# Some inputtypes, such as dynamath, have additional "hidden" state that
# is not exposed to the student. Keep those hidden
+ # TODO: Use regex, e.g. 'dynamath' is suffix at end of answer_id
hidden_state_keywords = ['dynamath']
for answer_id in answer_ids:
for hidden_state_keyword in hidden_state_keywords:
From f5d6f080c7dc05e78dafe6062dcd20e9049393df Mon Sep 17 00:00:00 2001
From: kimth
Date: Sun, 16 Sep 2012 00:47:40 -0400
Subject: [PATCH 4/6] Add basic styles
---
common/lib/xmodule/xmodule/capa_module.py | 14 +++++++-------
common/lib/xmodule/xmodule/css/capa/display.scss | 16 ++++++++++++++++
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 9eeaa57896..f6ba0d278d 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -256,16 +256,16 @@ class CapaModule(XModule):
seed=self.seed, system=self.system)
# Prepend a scary warning to the student
- warning = ''
- warning += '
Problem reset to initial state!
'
- warning += '
Problem state was corruped by invalid submission. The submission consisted of:
'
- warning += '
'
+ warning = ''\
+ '
Warning: Problem reset to initial state!
'\
+ 'Problem state was corruped by invalid submission. The submission consisted of:'\
+ '
'
for student_answer in student_answers.values():
if student_answer != '':
warning += '- ' + cgi.escape(student_answer) + '
'
- warning += '
'
- warning += '
If problem persists, please contact the course staff.
'
- warning += '
'
+ warning += '
'\
+ 'If problem persists, please contact the course staff.'\
+ '
'
html = warning
try:
diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss
index 0591a01843..944904ca54 100644
--- a/common/lib/xmodule/xmodule/css/capa/display.scss
+++ b/common/lib/xmodule/xmodule/css/capa/display.scss
@@ -465,6 +465,22 @@ section.problem {
margin-top: 10px;
}
+ div.capa_reset {
+ padding: 25px;
+ border: 1px solid #EBE8BF;
+ border-radius: 3px;
+ background: #FFFCDD;
+ font-size: 1em;
+ margin-top: 10px;
+ margin-bottom: 10px;
+ }
+ .capa_reset>h2 {
+ color: #FF0000;
+ }
+ .capa_reset li {
+ font-size: 0.9em;
+ }
+
.hints {
border: 1px solid #ccc;
From 2c239f87e890467111c1933b585a066c6aa658f5 Mon Sep 17 00:00:00 2001
From: kimth
Date: Sun, 16 Sep 2012 00:48:53 -0400
Subject: [PATCH 5/6] Change wording of warning slightly
---
common/lib/xmodule/xmodule/capa_module.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index f6ba0d278d..17b5e2921a 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -264,7 +264,7 @@ class CapaModule(XModule):
if student_answer != '':
warning += '' + cgi.escape(student_answer) + ''
warning += ''\
- 'If problem persists, please contact the course staff.'\
+ 'If the problem persists, please contact the course staff.'\
''
html = warning
From 7682663e1b90a1566bab37987df02b817863415a Mon Sep 17 00:00:00 2001
From: Arjun Singh
Date: Sat, 15 Sep 2012 22:07:10 -0700
Subject: [PATCH 6/6] Make broken problem error a bit scarier and fix typo in
message
---
common/lib/xmodule/xmodule/capa_module.py | 7 ++++---
common/lib/xmodule/xmodule/css/capa/display.scss | 6 +++---
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 17b5e2921a..a891474581 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -257,14 +257,15 @@ class CapaModule(XModule):
# Prepend a scary warning to the student
warning = ''\
- '
Warning: Problem reset to initial state!
'\
- 'Problem state was corruped by invalid submission. The submission consisted of:'\
+ '
Warning: The problem has been reset to its initial state!
'\
+ 'The problem\'s state was corrupted by an invalid submission. ' \
+ 'The submission consisted of:'\
'
'
for student_answer in student_answers.values():
if student_answer != '':
warning += '- ' + cgi.escape(student_answer) + '
'
warning += '
'\
- 'If the problem persists, please contact the course staff.'\
+ 'If this error persists, please contact the course staff.'\
'
'
html = warning
diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss
index 944904ca54..f349de31b5 100644
--- a/common/lib/xmodule/xmodule/css/capa/display.scss
+++ b/common/lib/xmodule/xmodule/css/capa/display.scss
@@ -467,15 +467,15 @@ section.problem {
div.capa_reset {
padding: 25px;
- border: 1px solid #EBE8BF;
+ border: 1px solid $error-red;
+ background-color: lighten($error-red, 25%);
border-radius: 3px;
- background: #FFFCDD;
font-size: 1em;
margin-top: 10px;
margin-bottom: 10px;
}
.capa_reset>h2 {
- color: #FF0000;
+ color: #AA0000;
}
.capa_reset li {
font-size: 0.9em;