Refactored CustomResponse to use the same private
func to handle all errors related to execution of python code. CustomResponse now returns subclasses of Exception instead of general Exceptions CustomResponse no longer includes tracebacks in the exceptions it raises (and shows to students)
This commit is contained in:
@@ -1072,13 +1072,11 @@ def sympy_check2():
|
||||
correct = self.context['correct']
|
||||
messages = self.context['messages']
|
||||
overall_message = self.context['overall_message']
|
||||
|
||||
except Exception as err:
|
||||
print "oops in customresponse (code) error %s" % err
|
||||
print "context = ", self.context
|
||||
print traceback.format_exc()
|
||||
# Notify student
|
||||
raise StudentInputError(
|
||||
"Error: Problem could not be evaluated with your input")
|
||||
self._handle_exec_exception(err)
|
||||
pass
|
||||
|
||||
else:
|
||||
# self.code is not a string; assume its a function
|
||||
|
||||
@@ -1105,13 +1103,9 @@ def sympy_check2():
|
||||
nargs, args, kwargs))
|
||||
|
||||
ret = fn(*args[:nargs], **kwargs)
|
||||
|
||||
except Exception as err:
|
||||
log.error("oops in customresponse (cfn) error %s" % err)
|
||||
# print "context = ",self.context
|
||||
log.error(traceback.format_exc())
|
||||
raise Exception("oops in customresponse (cfn) error %s" % err)
|
||||
log.debug(
|
||||
"[courseware.capa.responsetypes.customresponse.get_score] ret = %s" % ret)
|
||||
self._handle_exec_exception(err)
|
||||
|
||||
if type(ret) == dict:
|
||||
|
||||
@@ -1157,7 +1151,7 @@ def sympy_check2():
|
||||
# Raise an exception
|
||||
else:
|
||||
log.error(traceback.format_exc())
|
||||
raise Exception(
|
||||
raise LoncapaProblemError(
|
||||
"CustomResponse: check function returned an invalid dict")
|
||||
|
||||
# The check function can return a boolean value,
|
||||
@@ -1227,6 +1221,23 @@ def sympy_check2():
|
||||
return {self.answer_ids[0]: self.expect}
|
||||
return self.default_answer_map
|
||||
|
||||
def _handle_exec_exception(self, err):
|
||||
'''
|
||||
Handle an exception raised during the execution of
|
||||
custom Python code.
|
||||
|
||||
Raises a StudentInputError
|
||||
'''
|
||||
|
||||
# Log the error if we are debugging
|
||||
msg = 'Error occurred while evaluating CustomResponse: %s' % str(err)
|
||||
log.debug(msg)
|
||||
log.debug(traceback.format_exc())
|
||||
|
||||
# Notify student
|
||||
raise StudentInputError(
|
||||
"Error: Problem could not be evaluated with your input")
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import textwrap
|
||||
from . import test_system
|
||||
|
||||
import capa.capa_problem as lcp
|
||||
from capa.responsetypes import LoncapaProblemError, StudentInputError
|
||||
from capa.correctmap import CorrectMap
|
||||
from capa.util import convert_files_to_filenames
|
||||
from capa.xqueue_interface import dateformat
|
||||
@@ -853,7 +854,7 @@ class CustomResponseTest(ResponseTest):
|
||||
# Message is interpreted as an "overall message"
|
||||
self.assertEqual(correct_map.get_overall_message(), 'Message text')
|
||||
|
||||
def test_script_exception(self):
|
||||
def test_script_exception_function(self):
|
||||
|
||||
# Construct a script that will raise an exception
|
||||
script = textwrap.dedent("""
|
||||
@@ -864,7 +865,17 @@ class CustomResponseTest(ResponseTest):
|
||||
problem = self.build_problem(script=script, cfn="check_func")
|
||||
|
||||
# Expect that an exception gets raised when we check the answer
|
||||
with self.assertRaises(Exception):
|
||||
with self.assertRaises(StudentInputError):
|
||||
problem.grade_answers({'1_2_1': '42'})
|
||||
|
||||
def test_script_exception_inline(self):
|
||||
|
||||
# Construct a script that will raise an exception
|
||||
script = 'raise Exception("Test")'
|
||||
problem = self.build_problem(answer=script)
|
||||
|
||||
# Expect that an exception gets raised when we check the answer
|
||||
with self.assertRaises(StudentInputError):
|
||||
problem.grade_answers({'1_2_1': '42'})
|
||||
|
||||
def test_invalid_dict_exception(self):
|
||||
@@ -878,7 +889,7 @@ class CustomResponseTest(ResponseTest):
|
||||
problem = self.build_problem(script=script, cfn="check_func")
|
||||
|
||||
# Expect that an exception gets raised when we check the answer
|
||||
with self.assertRaises(Exception):
|
||||
with self.assertRaises(LoncapaProblemError):
|
||||
problem.grade_answers({'1_2_1': '42'})
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user