diff --git a/django/views/debug.py b/django/views/debug.py index 58dc4de9675..3b37e8da1a5 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -384,10 +384,12 @@ class ExceptionReporter: lower_bound = max(0, lineno - context_lines) upper_bound = lineno + context_lines - pre_context = source[lower_bound:lineno] - context_line = source[lineno] - post_context = source[lineno + 1:upper_bound] - + try: + pre_context = source[lower_bound:lineno] + context_line = source[lineno] + post_context = source[lineno + 1:upper_bound] + except IndexError: + return None, [], None, [] return lower_bound, pre_context, context_line, post_context def get_traceback_frames(self): diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 8e66bb3a036..80c92cf8c36 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -435,6 +435,40 @@ class ExceptionReporterTests(SimpleTestCase): text, ) + def test_reporting_frames_source_not_match(self): + try: + source = "def funcName():\n raise Error('Whoops')\nfuncName()" + namespace = {} + code = compile(source, 'generated', 'exec') + exec(code, namespace) + except Exception: + exc_type, exc_value, tb = sys.exc_info() + with mock.patch( + 'django.views.debug.ExceptionReporter._get_source', + return_value=['wrong source'], + ): + request = self.rf.get('/test_view/') + reporter = ExceptionReporter(request, exc_type, exc_value, tb) + frames = reporter.get_traceback_frames() + last_frame = frames[-1] + self.assertEqual(last_frame['context_line'], '') + self.assertEqual(last_frame['filename'], 'generated') + self.assertEqual(last_frame['function'], 'funcName') + self.assertEqual(last_frame['lineno'], 2) + html = reporter.get_traceback_html() + self.assertIn('generated in funcName, line 2', html) + self.assertIn( + '"generated", line 2, in funcName\n' + ' <source code not available>', + html, + ) + text = reporter.get_traceback_text() + self.assertIn( + '"generated", line 2, in funcName\n' + ' ', + text, + ) + def test_reporting_frames_for_cyclic_reference(self): try: def test_func():