Start to document and sanitize error messages
This commit is contained in:
@@ -157,6 +157,7 @@ class CombinedOpenEndedV1Module():
|
||||
try:
|
||||
self.display_due_date = dateutil.parser.parse(display_due_date_string)
|
||||
except ValueError:
|
||||
#This is a staff_facing_error
|
||||
log.error("Could not parse due date {0} for location {1}".format(display_due_date_string, location))
|
||||
raise
|
||||
else:
|
||||
@@ -168,6 +169,7 @@ class CombinedOpenEndedV1Module():
|
||||
self.grace_period = parse_timedelta(grace_period_string)
|
||||
self.close_date = self.display_due_date + self.grace_period
|
||||
except:
|
||||
#This is a staff_facing_error
|
||||
log.error("Error parsing the grace period {0} for location {1}".format(grace_period_string, location))
|
||||
raise
|
||||
else:
|
||||
@@ -662,7 +664,10 @@ class CombinedOpenEndedV1Module():
|
||||
if self.attempts > self.max_attempts:
|
||||
return {
|
||||
'success': False,
|
||||
'error': 'Too many attempts.'
|
||||
#This is a student_facing_error
|
||||
'error': ('You have attempted this question {0} times. '
|
||||
'You are only allowed to attempt it {1} times.').format(
|
||||
self.attempts, self.max_attempts)
|
||||
}
|
||||
self.state = self.INITIAL
|
||||
self.allow_reset = False
|
||||
@@ -801,6 +806,7 @@ class CombinedOpenEndedV1Descriptor(XmlDescriptor, EditingDescriptor):
|
||||
expected_children = ['task', 'rubric', 'prompt']
|
||||
for child in expected_children:
|
||||
if len(xml_object.xpath(child)) == 0:
|
||||
#This is a staff_facing_error
|
||||
raise ValueError("Combined Open Ended definition must include at least one '{0}' tag".format(child))
|
||||
|
||||
def parse_task(k):
|
||||
|
||||
@@ -71,6 +71,7 @@ class CombinedOpenEndedRubric(object):
|
||||
})
|
||||
success = True
|
||||
except:
|
||||
#This is a staff_facing_error
|
||||
error_message = "[render_rubric] Could not parse the rubric with xml: {0}".format(rubric_xml)
|
||||
log.exception(error_message)
|
||||
raise RubricParsingError(error_message)
|
||||
@@ -81,6 +82,7 @@ class CombinedOpenEndedRubric(object):
|
||||
success = rubric_dict['success']
|
||||
rubric_feedback = rubric_dict['html']
|
||||
if not success:
|
||||
#This is a staff_facing_error
|
||||
error_message = "Could not parse rubric : {0} for location {1}".format(rubric_string, location.url())
|
||||
log.error(error_message)
|
||||
raise RubricParsingError(error_message)
|
||||
@@ -90,12 +92,14 @@ class CombinedOpenEndedRubric(object):
|
||||
for category in rubric_categories:
|
||||
total = total + len(category['options']) - 1
|
||||
if len(category['options']) > (max_score_allowed + 1):
|
||||
#This is a staff_facing_error
|
||||
error_message = "Number of score points in rubric {0} higher than the max allowed, which is {1}".format(
|
||||
len(category['options']), max_score_allowed)
|
||||
log.error(error_message)
|
||||
raise RubricParsingError(error_message)
|
||||
|
||||
if total != max_score:
|
||||
#This is a staff_facing_error
|
||||
error_msg = "The max score {0} for problem {1} does not match the total number of points in the rubric {2}".format(
|
||||
max_score, location, total)
|
||||
log.error(error_msg)
|
||||
@@ -118,6 +122,7 @@ class CombinedOpenEndedRubric(object):
|
||||
categories = []
|
||||
for category in element:
|
||||
if category.tag != 'category':
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_categories] Expected a <category> tag: got {0} instead".format(category.tag))
|
||||
else:
|
||||
categories.append(self.extract_category(category))
|
||||
@@ -144,11 +149,13 @@ class CombinedOpenEndedRubric(object):
|
||||
self.has_score = True
|
||||
# if we are missing the score tag and we are expecting one
|
||||
elif self.has_score:
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category] Category {0} is missing a score".format(descriptionxml.text))
|
||||
|
||||
|
||||
# parse description
|
||||
if descriptionxml.tag != 'description':
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category]: expected description tag, got {0} instead".format(descriptionxml.tag))
|
||||
|
||||
description = descriptionxml.text
|
||||
@@ -159,6 +166,7 @@ class CombinedOpenEndedRubric(object):
|
||||
# parse options
|
||||
for option in optionsxml:
|
||||
if option.tag != 'option':
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category]: expected option tag, got {0} instead".format(option.tag))
|
||||
else:
|
||||
pointstr = option.get("points")
|
||||
@@ -168,6 +176,7 @@ class CombinedOpenEndedRubric(object):
|
||||
try:
|
||||
points = int(pointstr)
|
||||
except ValueError:
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category]: expected points to have int, got {0} instead".format(pointstr))
|
||||
elif autonumbering:
|
||||
# use the generated one if we're in the right mode
|
||||
@@ -218,12 +227,14 @@ class CombinedOpenEndedRubric(object):
|
||||
Validates a set of options. This can and should be extended to filter out other bad edge cases
|
||||
'''
|
||||
if len(options) == 0:
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category]: no options associated with this category")
|
||||
if len(options) == 1:
|
||||
return
|
||||
prev = options[0]['points']
|
||||
for option in options[1:]:
|
||||
if prev == option['points']:
|
||||
#This is a staff_facing_error
|
||||
raise RubricParsingError("[extract_category]: found duplicate point values between two different options")
|
||||
else:
|
||||
prev = option['points']
|
||||
@@ -232,11 +243,14 @@ class CombinedOpenEndedRubric(object):
|
||||
def reformat_scores_for_rendering(scores, score_types, feedback_types):
|
||||
success = False
|
||||
if len(scores)==0:
|
||||
log.error("Score length is 0.")
|
||||
#This is a dev_facing_error
|
||||
log.error("Score length is 0 when trying to reformat rubric scores for rendering.")
|
||||
return success, ""
|
||||
|
||||
if len(scores) != len(score_types) or len(feedback_types) != len(scores):
|
||||
log.error("Length mismatches.")
|
||||
#This is a dev_facing_error
|
||||
log.error("Length mismatches when trying to reformat rubric scores for rendering. "
|
||||
"Scores: {0}, Score Types: {1} Feedback Types: {2}".format(scores, score_types, feedback_types))
|
||||
return success, ""
|
||||
|
||||
score_lists = []
|
||||
|
||||
@@ -51,6 +51,8 @@ class GradingService(object):
|
||||
r = self._try_with_login(op)
|
||||
except (RequestException, ConnectionError, HTTPError) as err:
|
||||
# reraise as promised GradingServiceError, but preserve stacktrace.
|
||||
#This is a dev_facing_error
|
||||
log.error("Problem posting data to the grading controller. URL: {0}, data: {1}".format(url, data))
|
||||
raise GradingServiceError, str(err), sys.exc_info()[2]
|
||||
|
||||
return r.text
|
||||
@@ -67,6 +69,8 @@ class GradingService(object):
|
||||
r = self._try_with_login(op)
|
||||
except (RequestException, ConnectionError, HTTPError) as err:
|
||||
# reraise as promised GradingServiceError, but preserve stacktrace.
|
||||
#This is a dev_facing_error
|
||||
log.error("Problem getting data from the grading controller. URL: {0}, params: {1}".format(url, params))
|
||||
raise GradingServiceError, str(err), sys.exc_info()[2]
|
||||
|
||||
return r.text
|
||||
@@ -119,11 +123,13 @@ class GradingService(object):
|
||||
return response_json
|
||||
# if we can't parse the rubric into HTML,
|
||||
except etree.XMLSyntaxError, RubricParsingError:
|
||||
#This is a dev_facing_error
|
||||
log.exception("Cannot parse rubric string. Raw string: {0}"
|
||||
.format(rubric))
|
||||
return {'success': False,
|
||||
'error': 'Error displaying submission'}
|
||||
except ValueError:
|
||||
#This is a dev_facing_error
|
||||
log.exception("Error parsing response: {0}".format(response))
|
||||
return {'success': False,
|
||||
'error': "Error displaying submission"}
|
||||
|
||||
Reference in New Issue
Block a user