﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
31672	debug error view shows no traceback if exc.__traceback__ is None for innermost exception	Chris Jerdonek	Hasan Ramezani	"Consider this test view which raises an exception:

{{{
#!python
class TestView(View):

    def get(self, request, *args, **kwargs):
        try:
            raise RuntimeError('my error')
        except Exception as exc:
            # Uncommenting these two lines causes the debug
            # server error view not to show **any** portion
            # of the traceback.
            # new_exc = RuntimeError('my context')
            # exc.__context__ = new_exc

            raise
}}}

If the indicated lines are uncommented, then the debug error view shows no traceback info at all.

This is because `django.views.debug.get_traceback_frames()` starts at the innermost exception in the chain, and then stops adding frames when it encounters the first exception with `None`-valued `exc_value.__traceback__`:
https://github.com/django/django/blob/38a21f2d9ed4f556af934498ec6a242f6a20418a/django/views/debug.py#L391

{{{
#!python
exc_value = exceptions.pop()
tb = self.tb if not exceptions else exc_value.__traceback__

while tb is not None:
    # Get frame.
    ...
    frames.append({
        ...
    })

    # If the traceback for current exception is consumed, try the
    # other exception.
    if not tb.tb_next and exceptions:
        exc_value = exceptions.pop()
        tb = exc_value.__traceback__
    else:
        tb = tb.tb_next

return frames
}}}

It would probably be better and simpler if instead the while loop were structured to iterate over every exception in the chain no matter what, and include traceback info only for those exceptions with non-`None` `__traceback__`. In other words, something like the following:

{{{
#!python
while exceptions:
    exc_value = exceptions.pop()
    # Returns placeholder frame with no `tb` info if
    # `exc_value.__traceback__ is None`.
    exc_frames = self.get_traceback_frames(exc_value)
    frames.extend(exc_frames)
}}}

This way, the debug error view would always show the complete exception chain, even if some exceptions in the chain have a `None`-valued traceback attribute."	Cleanup/optimization	closed	Error reporting	dev	Normal	fixed	technical_500_response,traceback,chain		Ready for checkin	1	0	0	0	0	0
