Commit 285e3ee1 by Will Daly

Capa response now displays full stack trace on student input error

if the user is a staff member.
Otherwise, it displays just the exception message.
parent cd6f92c7
...@@ -17,6 +17,7 @@ import logging ...@@ -17,6 +17,7 @@ import logging
import numbers import numbers
import numpy import numpy
import os import os
import sys
import random import random
import re import re
import requests import requests
...@@ -1233,9 +1234,9 @@ def sympy_check2(): ...@@ -1233,9 +1234,9 @@ def sympy_check2():
log.debug(msg, exc_info=True) log.debug(msg, exc_info=True)
log.debug(traceback.format_exc()) log.debug(traceback.format_exc())
# Notify student # Notify student with a student input error
raise StudentInputError( _, _, traceback_obj = sys.exc_info()
"Error: Problem could not be evaluated with your input") raise StudentInputError, StudentInputError(err.message), traceback_obj
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
......
...@@ -725,9 +725,23 @@ class CapaModule(CapaFields, XModule): ...@@ -725,9 +725,23 @@ class CapaModule(CapaFields, XModule):
try: try:
correct_map = self.lcp.grade_answers(answers) correct_map = self.lcp.grade_answers(answers)
self.set_state_from_lcp() self.set_state_from_lcp()
except StudentInputError as inst: except StudentInputError as inst:
log.exception("StudentInputError in capa_module:problem_check") log.exception("StudentInputError in capa_module:problem_check")
return {'success': inst.message}
# If the user is a staff member, include
# the full exception, including traceback,
# in the response
if self.system.user_is_staff:
msg = traceback.format_exc()
# Otherwise, display just the error message,
# without a stack trace
else:
msg = inst.message
return {'success': msg }
except Exception, err: except Exception, err:
if self.system.DEBUG: if self.system.DEBUG:
msg = "Error checking problem: " + str(err) msg = "Error checking problem: " + str(err)
......
...@@ -505,6 +505,9 @@ class CapaModuleTest(unittest.TestCase): ...@@ -505,6 +505,9 @@ class CapaModuleTest(unittest.TestCase):
def test_check_problem_student_input_error(self): def test_check_problem_student_input_error(self):
module = CapaFactory.create(attempts=1) module = CapaFactory.create(attempts=1)
# Ensure that the user is NOT staff
module.system.user_is_staff = False
# Simulate a student input exception # Simulate a student input exception
with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade: with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade:
mock_grade.side_effect = capa.responsetypes.StudentInputError('test error') mock_grade.side_effect = capa.responsetypes.StudentInputError('test error')
...@@ -515,10 +518,32 @@ class CapaModuleTest(unittest.TestCase): ...@@ -515,10 +518,32 @@ class CapaModuleTest(unittest.TestCase):
# Expect an AJAX alert message in 'success' # Expect an AJAX alert message in 'success'
self.assertTrue('test error' in result['success']) self.assertTrue('test error' in result['success'])
# We do NOT include traceback information for
# a non-staff user
self.assertFalse('Traceback' in result['success'])
# Expect that the number of attempts is NOT incremented # Expect that the number of attempts is NOT incremented
self.assertEqual(module.attempts, 1) self.assertEqual(module.attempts, 1)
def test_check_problem_student_input_error_with_staff_user(self):
module = CapaFactory.create(attempts=1)
# Ensure that the user IS staff
module.system.user_is_staff = True
# Simulate a student input exception
with patch('capa.capa_problem.LoncapaProblem.grade_answers') as mock_grade:
mock_grade.side_effect = capa.responsetypes.StudentInputError('test error')
get_request_dict = { CapaFactory.input_key(): '3.14'}
result = module.check_problem(get_request_dict)
# Expect an AJAX alert message in 'success'
self.assertTrue('test error' in result['success'])
# We DO include traceback information for staff users
self.assertTrue('Traceback' in result['success'])
def test_reset_problem(self): def test_reset_problem(self):
module = CapaFactory.create(done=True) module = CapaFactory.create(done=True)
module.new_lcp = Mock(wraps=module.new_lcp) module.new_lcp = Mock(wraps=module.new_lcp)
......
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