From 285e3ee1edfbb5cbb22f821b05b7a752aab25c73 Mon Sep 17 00:00:00 2001 From: Will Daly Date: Wed, 27 Mar 2013 10:49:47 -0400 Subject: [PATCH] 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. --- common/lib/capa/capa/responsetypes.py | 7 +++--- common/lib/xmodule/xmodule/capa_module.py | 16 +++++++++++- .../xmodule/xmodule/tests/test_capa_module.py | 25 +++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 2c556211f8..465c212b30 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -17,6 +17,7 @@ import logging import numbers import numpy import os +import sys import random import re import requests @@ -1233,9 +1234,9 @@ def sympy_check2(): log.debug(msg, exc_info=True) log.debug(traceback.format_exc()) - # Notify student - raise StudentInputError( - "Error: Problem could not be evaluated with your input") + # Notify student with a student input error + _, _, traceback_obj = sys.exc_info() + raise StudentInputError, StudentInputError(err.message), traceback_obj #----------------------------------------------------------------------------- diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index da8b5b4f96..203e14fdc1 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -725,9 +725,23 @@ class CapaModule(CapaFields, XModule): try: correct_map = self.lcp.grade_answers(answers) self.set_state_from_lcp() + except StudentInputError as inst: 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: if self.system.DEBUG: msg = "Error checking problem: " + str(err) diff --git a/common/lib/xmodule/xmodule/tests/test_capa_module.py b/common/lib/xmodule/xmodule/tests/test_capa_module.py index d2458cb3d0..d769b65914 100644 --- a/common/lib/xmodule/xmodule/tests/test_capa_module.py +++ b/common/lib/xmodule/xmodule/tests/test_capa_module.py @@ -505,6 +505,9 @@ class CapaModuleTest(unittest.TestCase): def test_check_problem_student_input_error(self): module = CapaFactory.create(attempts=1) + # Ensure that the user is NOT staff + module.system.user_is_staff = False + # 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') @@ -515,10 +518,32 @@ class CapaModuleTest(unittest.TestCase): # Expect an AJAX alert message in '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 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): module = CapaFactory.create(done=True) module.new_lcp = Mock(wraps=module.new_lcp)