Skip to content

Commit 71d3957

Browse files
gagerntimgraham
authored andcommitted
Fixed #28485 -- Made ExceptionReporter.get_traceback_frames() include frames without source code.
1 parent 90d7b91 commit 71d3957

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ answer newbie questions, and generally made Django that much better:
514514
Martin Kosír <martin@martinkosir.net>
515515
Martin Mahner <http://www.mahner.org/>
516516
Martin Maney <http://www.chipy.org/Martin_Maney>
517+
Martin von Gagern <gagern@google.com>
517518
Mart Sõmermaa <http://mrts.pri.ee/>
518519
Marty Alchin <gulopine@gamemusic.org>
519520
masonsimon+django@gmail.com

django/views/debug.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -418,22 +418,26 @@ def explicit_or_implicit_cause(exc_value):
418418
pre_context_lineno, pre_context, context_line, post_context = self._get_lines_from_file(
419419
filename, lineno, 7, loader, module_name,
420420
)
421-
if pre_context_lineno is not None:
422-
frames.append({
423-
'exc_cause': explicit_or_implicit_cause(exc_value),
424-
'exc_cause_explicit': getattr(exc_value, '__cause__', True),
425-
'tb': tb,
426-
'type': 'django' if module_name.startswith('django.') else 'user',
427-
'filename': filename,
428-
'function': function,
429-
'lineno': lineno + 1,
430-
'vars': self.filter.get_traceback_frame_variables(self.request, tb.tb_frame),
431-
'id': id(tb),
432-
'pre_context': pre_context,
433-
'context_line': context_line,
434-
'post_context': post_context,
435-
'pre_context_lineno': pre_context_lineno + 1,
436-
})
421+
if pre_context_lineno is None:
422+
pre_context_lineno = lineno
423+
pre_context = []
424+
context_line = '<source code not available>'
425+
post_context = []
426+
frames.append({
427+
'exc_cause': explicit_or_implicit_cause(exc_value),
428+
'exc_cause_explicit': getattr(exc_value, '__cause__', True),
429+
'tb': tb,
430+
'type': 'django' if module_name.startswith('django.') else 'user',
431+
'filename': filename,
432+
'function': function,
433+
'lineno': lineno + 1,
434+
'vars': self.filter.get_traceback_frame_variables(self.request, tb.tb_frame),
435+
'id': id(tb),
436+
'pre_context': pre_context,
437+
'context_line': context_line,
438+
'post_context': post_context,
439+
'pre_context_lineno': pre_context_lineno + 1,
440+
})
437441

438442
# If the traceback for current exception is consumed, try the
439443
# other exception.

tests/view_tests/tests/test_debug.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,27 @@ def test_reporting_of_nested_exceptions(self):
375375
self.assertIn(implicit_exc.format("Second exception"), text)
376376
self.assertEqual(3, text.count('<p>Final exception</p>'))
377377

378+
def test_reporting_frames_without_source(self):
379+
try:
380+
source = "def funcName():\n raise Error('Whoops')\nfuncName()"
381+
namespace = {}
382+
code = compile(source, 'generated', 'exec')
383+
exec(code, namespace)
384+
except Exception:
385+
exc_type, exc_value, tb = sys.exc_info()
386+
request = self.rf.get('/test_view/')
387+
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
388+
frames = reporter.get_traceback_frames()
389+
last_frame = frames[-1]
390+
self.assertEqual(last_frame['context_line'], '<source code not available>')
391+
self.assertEqual(last_frame['filename'], 'generated')
392+
self.assertEqual(last_frame['function'], 'funcName')
393+
self.assertEqual(last_frame['lineno'], 2)
394+
html = reporter.get_traceback_html()
395+
self.assertIn('generated in funcName', html)
396+
text = reporter.get_traceback_text()
397+
self.assertIn('"generated" in funcName', text)
398+
378399
def test_request_and_message(self):
379400
"A message can be provided in addition to a request"
380401
request = self.rf.get('/test_view/')

0 commit comments

Comments
 (0)