Opened 10 years ago
Closed 10 years ago
#23643 closed New feature (fixed)
Have debug page show "During handling of this exception, another exception occurred.."
Reported by: | Ram Rachum | Owned by: | Tomáš Ehrlich |
---|---|---|---|
Component: | Core (Other) | Version: | dev |
Severity: | Release blocker | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Python 3 has this thing where exceptions have optional __cause__
and __context__
, which is useful when an exception causes another exception. When you get a Python 3 traceback, you see tracebacks for all the exceptions in the tree. Currently it seems that the Django debug page ignores this information. It would be nice if it would display a separate traceback for each such exception.
Change History (15)
comment:1 by , 10 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Version: | 1.7 → master |
comment:3 by , 10 years ago
Has patch: | set |
---|
comment:4 by , 10 years ago
The easiest way to review, hook up this view into your urlconf:
def chained_exception(request): try: raise AttributeError('Top level') except AttributeError as explicit: try: raise ValueError('Second exception') from explicit except ValueError: raise IndexError('Final exception')
comment:5 by , 10 years ago
Component: | Python 3 → Core (Other) |
---|
comment:7 by , 10 years ago
Has patch: | unset |
---|---|
Resolution: | fixed |
Severity: | Normal → Release blocker |
Status: | closed → new |
Ran into a crash (Python 2 only) when a view raised an IntegrityError
:
Traceback (most recent call last): File "/usr/lib/python2.7/wsgiref/handlers.py", line 85, in run self.result = application(self.environ, self.start_response) File "/home/tim/code/django/django/contrib/staticfiles/handlers.py", line 63, in __call__ return self.application(environ, start_response) File "/home/tim/code/django/django/core/handlers/wsgi.py", line 177, in __call__ response = self.get_response(request) File "/home/tim/code/django/django/core/handlers/base.py", line 218, in get_response response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) File "/home/tim/code/django/django/core/handlers/base.py", line 261, in handle_uncaught_exception return debug.technical_500_response(request, *exc_info) File "/home/tim/code/django/django/views/debug.py", line 97, in technical_500_response html = reporter.get_traceback_html() File "/home/tim/code/django/django/views/debug.py", line 387, in get_traceback_html c = Context(self.get_traceback_data(), use_l10n=False) File "/home/tim/code/django/django/views/debug.py", line 332, in get_traceback_data frames = self.get_traceback_frames() File "/home/tim/code/django/django/views/debug.py", line 503, in get_traceback_frames tb = self.tb if not exceptions else exc_value.__traceback__ AttributeError: 'IntegrityError' object has no attribute '__traceback__'
comment:8 by , 10 years ago
Has patch: | set |
---|---|
Status: | new → assigned |
- I've submitted new PR with updated plain-text output https://github.com/django/django/pull/4412
- I couldn't reproduce the AttributeError. I tried this simple view:
def view(request): raise IntegrityError('Error raised')
We could simple replace this line:
tb = self.tb if not exceptions else exc_value.__traceback__
with safer, but longer:
if not exceptions or not hasattr(exc_value, '__traceback__'): tb = self.tb else: tb = exc_value.__traceback__
The point was that exceptions
should have been already empty in Python 2, but somewhat it wasn't. Would be great if we could reproduce your problem.
comment:9 by , 10 years ago
Patch needs improvement: | set |
---|
Here's a view to reproduce AttributeError: 'IntegrityError' object has no attribute '__traceback__'
:
def vote(request, poll_id): Question.objects.create(question_text='foobar')
comment:10 by , 10 years ago
See the PR https://github.com/django/django/pull/4530 for more details.
comment:11 by , 10 years ago
And the PR https://github.com/django/django/pull/4568 for regression tests
the cause attribute is set in db/utils.py in wrapping DatabaseException
comment:13 by , 10 years ago
Needs tests: | set |
---|---|
Patch needs improvement: | unset |
The one item remaining is adding a test for the plain text exception chain report. Tomas said he will do that soon.
comment:15 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
In 59383f1e3a8ab5a6477dbd5bb1d7c32366a9d8f8:
Ref #23643 -- Added plain text report of exception chain.
I like this idea.
I find that it really helps with debugging (especially when Django has a bad habit of masking exceptions).