Maybe this question has already been asked, but I am wondering why Jinja2
compatibility can't be fixed in a clean way. Currently the code assumes that
if an exception has a "source" attribute that it's a Django exception and can
be processed as such. (the code:
http://code.djangoproject.com/browser/django/trunk/django/views/debug.py#L87 )
However, if all template exceptions have the same base exception (as they
logically should) wouldn't it automatically work if you simply test for the
exception?
There has been a previous ticket with a hacky solution:
http://code.djangoproject.com/ticket/10216
But I feel that testing for specific exceptions (as any try/except should)
would make the code cleaner and fix this problem. Assuming that any exception
with a source attribute can be processed as the expected Django exception is
simply wrong.
Right now you can break the entire debugging system by simply raising an
exception like this:
class MyException(Exception):
source = 'Breaking the Django template debugger'
~Rick
There is an important difference between "can't" and "hasn't". The
Django core's development priority is Django, and Django is a
'batteries included' framework. As a result, our development priority
is in making Django's template language better.
We are open to making any changes that make it easier to plug in
different template engines or ORMs (or any other external component).
We (the core) just haven't spent a lot of development time trying to
reach that particular goal.
If someone in the community wants to pursue this goal, they are
welcome to do so. Propose a patch, and as long as it doesn't
fundamentally compromise the design of Django, it stands a good chance
of getting into trunk.
> However, if all template exceptions have the same base exception (as they
> logically should) wouldn't it automatically work if you simply test for the
> exception?
No, it wouldn't (at least, not completely). Jinja wouldn't extend
Django's TemplateSyntaxError class, so using the approach you
describe, Jinja's TemplateSyntaxErrors wouldn't break the debug page,
but you wouldn't get good template error feedback either.
> There has been a previous ticket with a hacky solution:
> http://code.djangoproject.com/ticket/10216
>
> But I feel that testing for specific exceptions (as any try/except should)
> would make the code cleaner and fix this problem. Assuming that any exception
> with a source attribute can be processed as the expected Django exception is
> simply wrong.
I disagree. Checking for capabilities rather than types is the
cornerstone of duck typing. In this case, Jinja's TemplateSyntaxError
doesn't quack in quite the same way as Django's duck. I can see three
possible solutions:
1) The capability check isn't rigorous enough. Modify the capability
check to make it more specific.
2) Push the problem back to Jinja. As Malcolm's comment on #10216
notes, Django has a protocol for template errors and doesn't make any
claim to having Jinja compatibility. If Jinja makes claims to Django
compatibility but doesn't adhere to that protocol, then it's up to
Jinja to fix the problem.
3) Come up with a new capability that can be used instead.
From a cursory inspection, I'm not sure there is much we can do with
(1) - there isn't a lot of detail on Exception that can be used for a
capability check, and the only attribute that is actually needed is
'source' (albeit in a particular format that evidently Jinja doesn't
use).
(2) isn't Django's problem to fix.
(3) Seems like the most promising option. For example, most of the
call to ExceptionReporter .get_template_exception_info() could be
deferred to the exception itself. If we refactored that code into a
method on the exception itself, we could use that method as the
capability that we check for. It would be less ambiguous (not many
exceptions would have a 'get_template_exception_info' method), and it
would allow *any* exception (template or otherwise) to raise an
embedded exception that provided template details on the technical 500
page.
However, as I said originally - the existing setup works for Django at
present. If you want to improve support for Jinja... patches are
accepted :-)
Yours
Russ Magee %-)
FWIW, I don't think that's an issue; Jinja 2 has it's own debug mode
it which it rewrites an exception's stack trace with line numbers from
the raw template, so I don't think TEMPLATE_DEBUG would give any
additional benefit anyway.
Michael
Agreed, that is why the patch in the referenced ticket was denied.
http://code.djangoproject.com/attachment/ticket/10216/10216.diff
> (2) isn't Django's problem to fix.
If it would just be a problem with Jinja than I would agree. However, Django
breaks on every Exception with a source attribute that doesn't follow the
Django style completely.
> (3) Seems like the most promising option. For example, most of the
> call to ExceptionReporter .get_template_exception_info() could be
> deferred to the exception itself. If we refactored that code into a
> method on the exception itself, we could use that method as the
> capability that we check for. It would be less ambiguous (not many
> exceptions would have a 'get_template_exception_info' method), and it
> would allow *any* exception (template or otherwise) to raise an
> embedded exception that provided template details on the technical 500
> page.
Agreed, that would probably be the best solution. Although I do think that
duck typing for catching exceptions is generally not the way to go.
Exceptions should always be caught explicitly
> However, as I said originally - the existing setup works for Django at
> present. If you want to improve support for Jinja... patches are
> accepted :-)
As soon as I get back to the latest trunk release (I'm currently working on a
revision that's about a year old) I will write a patch for this problem.
Patching the old release and merging it with the current changes looks like
it is going to be quite a tedious process.
~Rick