Opened 7 years ago

Closed 7 years ago

#6862 closed (fixed)

Stack traces from non-DEBUG exceptions can't find source lines when DEBUG 500 pages can.

Reported by: nedbatchelder Owned by: mtredinnick
Component: Core (Other) Version: master
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

The DEBUG exception page uses its own code to load source lines and produce a stack trace. If DEBUG is false, the traceback module is used instead. In some environments, the DEBUG code will find source lines when the traceback module will not. For example, we run our code from an egg under 2.4, and traceback can't find the source.

This patch refactors the exception reporting in the debug code so that the non-debug case can make use of it to produce the same simple stack trace, but with the full power to load source from exotic locations.

The refactoring in views/debug.py is significant, but is pure refactoring. There had been a number of functions in the views/debug.py module which manipulated the exception values, and built stack traces. These have been unified into a class. This simplifies the data flow, since we no longer have functions taking and returning three or four values (a sure code smell that a class is appropriate).

Attachments (1)

6862_stack_reporting.diff (17.2 KB) - added by nedbatchelder 7 years ago.
The patch

Download all attachments as: .zip

Change History (5)

Changed 7 years ago by nedbatchelder

The patch

comment:1 Changed 7 years ago by nedbatchelder

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

One other thing to note about the patch: when the time comes to invoke the views/debug.py code in handlers/base.py, it's all wrapped in a raw try/except to prevent problems in the stack tracer from preventing reporting the original error.

comment:2 Changed 7 years ago by telenieko

  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 7 years ago by mtredinnick

  • Owner changed from nobody to mtredinnick

So this looks like a good idea and fits in with some other refactoring we need to do there. There's one small drawback; this change means that the debug code handling is always loaded even when DEBUG=False. That's a slight extra bit of memory usage that Adrian, in particular, likes to avoid and I don't mind his approach as a general guideline either.

Pulling this stuff out certainly allows somebody to easily subclass the django.core.handlers.* class of their choice and override the _get_traceback() method. I similarly want to pull out some of the other 500 handling so that, e.g, you're not required to have the emailing happen and that will be done via subclassing as well.

So I'll take care of committing this, but I don't think it will be on by default. It will be available to request/response handling subclasses, though, which is a nice way things both ways.

comment:4 Changed 7 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

(In [7927]) Fixed #6862 -- Refactored debug traceback extraction into an easy-to-use class.

Aside from being a little easier to read and use, this means you could subclass
a request/response handler class (from django.core.handlers) to add your own
traceback extraction handling in non-DEBUG environments and reuse this code.
Thanks, Ned Batchelder.

Note: See TracTickets for help on using tickets.
Back to Top