Rethinking silent failures in templates

952 views
Skip to first unread message

Simon Willison

unread,
May 14, 2008, 9:58:52 AM5/14/08
to Django developers
Hi all,

Some time in late 2003, Adrian and I decided that errors in templates
were best handled silently - the idea was that it would prevent
untrained template editors from being able to 500-error a site with a
typo.

Is it too late to reconsider this decision, four and a half years
later? I can't think of a single time this feature has helped me, and
plenty of examples of times that it has tripped me up.

Today's example: a <form action=""> tag that shouldn't have been
blank. The code looked like this:

<form action="{% url something-with-a-typo %}">

If you look at Django's URL tag implementation, you can see why:

http://code.djangoproject.com/browser/django/trunk/django/template/defaulttags.py?rev=6996#L364

The code catches the NoReverseMatch exception and silences it,
outputting an empty string instead.

Silent errors are bad. If we were to remove them, how much of a
negative impact would it have on the existing user base?

Cheers,

Simon


George Vilches

unread,
May 14, 2008, 10:02:59 AM5/14/08
to django-d...@googlegroups.com

On May 14, 2008, at 9:58 AM, Simon Willison wrote:
> Silent errors are bad. If we were to remove them, how much of a
> negative impact would it have on the existing user base?

I suspect that a lot of people actually rely on this behavior, and it
would be devastating to them. What I've personally hoped for (besides
a pony) was a bit of both: a development mode where I could turn on
template errors and have them trickle to me, and then a setting that
allows me to turn that off in production. That's the best of both
worlds, and I'm sure makes the template code ridiculously more
complicated so it probably won't happen. But I'd still like it.

gav

Simon Willison

unread,
May 14, 2008, 10:07:05 AM5/14/08
to Django developers
On May 14, 3:02 pm, George Vilches <g...@thataddress.com> wrote:
> On May 14, 2008, at 9:58 AM, Simon Willison wrote:
> > Silent errors are bad. If we were to remove them, how much of a
> > negative impact would it have on the existing user base?
>
> I suspect that a lot of people actually rely on this behavior, and it
> would be devastating to them.

Thinking about it some more you're right - I'm sure there are lots of
cases where people are relying on things like the following:

{{ article.something.title }} - outputs text if article is there,
fails silently otherwise

Which leaves us in a tricky situation. A global settings.py variable
for "throw errors on missing template variables" is a bad idea as it
kills application portability (the PHP magic_quotes problem again - if
your application expects that setting off and mine expects it on I
can't import your app in to my environment). There might be something
we can do with warnings, but it could still end up pretty messy. Needs
more thought.

Deryck Hodge

unread,
May 14, 2008, 10:10:05 AM5/14/08
to django-d...@googlegroups.com
On Wed, May 14, 2008 at 9:07 AM, Simon Willison <si...@simonwillison.net> wrote:
> Which leaves us in a tricky situation. A global settings.py variable
> for "throw errors on missing template variables" is a bad idea as it
> kills application portability (the PHP magic_quotes problem again - if
> your application expects that setting off and mine expects it on I
> can't import your app in to my environment). There might be something
> we can do with warnings, but it could still end up pretty messy. Needs
> more thought.

Hi, Simon.

Could you not just tie it to the DEBUG setting? That is the worry,
after all, right? -- that a production site will 500. Development it
doesn't matter, and generally, people use DEBUG to distinguish the
two.

Just a quick thought... I haven't looked at the code to know the
implications of using DEBUG as the flag.

Cheers,
deryck


--
Deryck Hodge
http://www.devurandom.org/

Marty Alchin

unread,
May 14, 2008, 10:22:39 AM5/14/08
to django-d...@googlegroups.com
On Wed, May 14, 2008 at 10:07 AM, Simon Willison
<si...@simonwillison.net> wrote:
>> I suspect that a lot of people actually rely on this behavior, and it
>> would be devastating to them.
>
> Thinking about it some more you're right - I'm sure there are lots of
> cases where people are relying on things like the following:
>
> {{ article.something.title }} - outputs text if article is there,
> fails silently otherwise

I'm not expert on the history of this or anything, but I always
thought this example was the basis for silent errors. That makes me
wonder, then, if there's some other kind of separation we can have.
Perhaps variable lookups continue to fail silently, regardless of
environment, while actual {% ... %} tags raise errors by default.

Of course, there's still something to be said for using DEBUG to show
errors in development, while not in production, and individual tags
would obviously be able to suppress their own errors if they choose
to, but I think it might work.

And at the risk of supplying too many possibilities for one email, the
magic_quotes problem could be avoided similarly to autoescaping.
Essentially, provide an extra argument to all the template rendering
functions, with a default based on the DEBUG (or other) setting.
Something like def render(self, context, silent_errors=not
settings.DEBUG). Then, individual apps can specify their behavior
explicitly if they need to, while relying on the setting if they
don't.

I'm probably way off-base on these ideas, though, because it would
likely lead to a lot of "hey, why is this template erroring out, while
this other one isn't?" I dunno. This email was probably too
stream-of-consciousness to be of any use. But there it is.

-Gul

Waylan Limberg

unread,
May 14, 2008, 10:43:28 AM5/14/08
to django-d...@googlegroups.com
On Wed, May 14, 2008 at 10:10 AM, Deryck Hodge <der...@samba.org> wrote:
>
> On Wed, May 14, 2008 at 9:07 AM, Simon Willison <si...@simonwillison.net> wrote:
> > Which leaves us in a tricky situation. A global settings.py variable
> > for "throw errors on missing template variables" is a bad idea as it
> > kills application portability (the PHP magic_quotes problem again - if
> > your application expects that setting off and mine expects it on I
> > can't import your app in to my environment). There might be something
> > we can do with warnings, but it could still end up pretty messy. Needs
> > more thought.
>
> Hi, Simon.
>
> Could you not just tie it to the DEBUG setting? That is the worry,
> after all, right? -- that a production site will 500. Development it
> doesn't matter, and generally, people use DEBUG to distinguish the
> two.
>
Well, say I have a template in which {{ article.something.title }} is
expected to fail silently in some cases. Suppose I also happen to have
another bug later in that template. In development (DEBUG mode on), I
don't want {{ article.something.title }} to generate an error, but I
do want that other later (as yet unknown) problem to give me django's
handy error page. If it always trips up on {{ article.something.title
}}, I'll never get to that other error which happens later in the
processing until I move to production and no longer get nice error
pages to help me find it.

Therefore, I think we need a way to distinguish between what parts of
the template should fail silently, and what parts should not. Perhaps
some sort of filter or tag or combination thereof. Not unlike
autoescaping -- fail by default and fail silently only were
explicitly set. Of course, this opens up a whole can-of-worms
regarding whether one tag affects the whole template, inherited
templates, a block in the template, or just a single variable lookup
or some combination of them all. Ug - don't want to go through that
again.

Hmm, before I posted this, I see that Marty has similar thoughts.
Maybe it's not so crazy after all.

--
----
Waylan Limberg
way...@gmail.com

Ken Arnold

unread,
May 14, 2008, 10:51:44 AM5/14/08
to Django developers
I made some comments on bug #5140 a while back, before I realized that
bug reports weren't a great place to discuss important things. That
bug bit me quite enough back in the early days of my project.

I'd definitely want to know if any url templatetag failed. And
probably any variable lookup also; if I didn't put |default:"" after
it, I probably wanted that value.

How's this for a prototype idea:
1. Production sites (DEBUG=False) keep the current behavior. Period.
The rest of this only applies if TEMPLATE_DEBUG is on.
2. If the docs specify specific failure behavior (like for first,
etc.), the docs win.
3. Tags and filters that specify the syntax of their output (e.g., the
output of a url tag should be a URL) fail if they can't provide that
output.
4. Other tags and filters, like include, ssi, and truncatewords (from
a quick scan) that perform some function that could fail, should mark
that failure very clearly in the output. (Those two currently do, but
the error string is easy to miss if buried in a mess of other code.)
5. Variable lookups, and everything else, never cause render() to
fail, but insert an easy-to-catch and easy-to-bypass error string in
the output.

So what is that error string? First of all, it should be something for
which bool(x) is False, so that defaulting, etc. all work as expected.
But if it does make it to the output, I see two choices:

a. Make its presence very well known. All caps text, ASCII art, etc.
b. Keep it on the down-low. HTML comment, for example.

My preference is for the first, partially because an HTML comment
might not be appropriate in the context.

But either way, the error string should have some known pattern that a
middleware could look for and report an exception for.

It could also log a message in its __str__ method.

Thoughts?
-Ken


On May 14, 9:58 am, Simon Willison <si...@simonwillison.net> wrote:
> Hi all,
>
> Some time in late 2003, Adrian and I decided that errors in templates
> were best handled silently - the idea was that it would prevent
> untrained template editors from being able to 500-error a site with a
> typo.
>
> Is it too late to reconsider this decision, four and a half years
> later? I can't think of a single time this feature has helped me, and
> plenty of examples of times that it has tripped me up.
>
> Today's example: a <form action=""> tag that shouldn't have been
> blank. The code looked like this:
>
> <form action="{% url something-with-a-typo %}">
>
> If you look at Django's URL tag implementation, you can see why:
>
> http://code.djangoproject.com/browser/django/trunk/django/template/de...

Ivan Sagalaev

unread,
May 14, 2008, 11:00:04 AM5/14/08
to django-d...@googlegroups.com
Simon Willison wrote:
> {{ article.something.title }} - outputs text if article is there,
> fails silently otherwise
>
> Which leaves us in a tricky situation. A global settings.py variable
> for "throw errors on missing template variables" is a bad idea as it
> kills application portability

It doesn't if we clearly document that silent beahviour is for
production and breakage is for debug. This setting won't travel with
application code but will be right alongside DEBUG in settings. Actually
there is such setting: TEMPLATE_DEBUG. We can just add this braking
effect to it. I believe it's pretty intuitive.

David Zhou

unread,
May 14, 2008, 11:38:38 AM5/14/08
to django-d...@googlegroups.com
I like the filter idea -- maybe something like 'required' It could be
similar to marking things as safe for the autoescaping.

Default behavior should be silent failures, and authors can explicitly
set variable calls to fail visibly.

So with Simon's original example, the template author would realize
that this is something that should not be blank, and do:

<form action="{% url something-with-a-typo|required %}">

But then with normal variable calls, would fail silently as usual:

{{ article.something.title }}

Nicola Larosa (tekNico)

unread,
May 14, 2008, 12:24:31 PM5/14/08
to Django developers
Simon Willison wrote:
> Silent errors are bad. If we were to remove them, how much of a
> negative impact would it have on the existing user base?

+1 from me.

I always set TEMPLATE_DEBUG to True and TEMPLATE_STRING_IF_INVALID to
something that stands out, during development.

--
Nicola Larosa - http://www.tekNico.net/

J. Cliff Dyer

unread,
May 14, 2008, 12:29:14 PM5/14/08
to django-d...@googlegroups.com

-1

I'm a fairly strong -1 on adding this across the board to debug
behavior, especially if it causes the template not to render. If having
a variable missing is expected behavior in some cases, and should result
in nothing being inserted, (and it frequently is for me) then causing
the page to break will make actual debugging impossible.

On the other hand, I'm +1 on the idea of having a filter to mark a
variable as required.

Cheers,
Cliff


George Vilches

unread,
May 14, 2008, 1:15:37 PM5/14/08
to django-d...@googlegroups.com

I mirror these sentiments exactly, with one exception. I don't think
filters are the right way to do this, for two reasons:

1) It's very limiting. There's lots of places that filters can't be
applied cleanly that would still make sense to have some subset of
behavior like this
2) It seems impossible. How can you have a filter that checks whether
the scope of some variable existed in a previous call, since the
filter only runs on the *output* of that variable evaluations.

So, here's my two cents (Marty, apologies, as I think I'm copying some
of your idea, but I needed my own stream of consciousness post). Why
not use a block tag, much like autoescape, to indicate that all
variables in this scope are required, and tie it to a custom exception.

The benefits as I see it:

1) This doesn't actually cause a schism between development and
production, as the block tag works the same in both cases. If we
really wanted a "this should be turned off in production no matter
what", it could be a settings flag, although I'm -0 on that.
2) By using a custom exception, any other block tag or filter inside
this scope could throw the same exception. It wouldn't affect anyone
normally as the template handler would catch it, but it would allow
people building their own tags to get the same sort of functionality
as internal variable resolutions, allowing block tags to force
required. (At least, when wrapped).
3) It's backwards-compatible. People not using the block tag aren't
affected.
4) It doesn't require any new syntactic sugar or assumptions. It's
just another block tag. We might modify a few existing block tags or
filters to be able to take advantage of it.

The negatives that I can think of right now:

1) It doesn't magically apply to all your templates. I think this is
a good thing, it's just like autoescape, if you're using it you
probably know what you're doing and why, but I think some people may
argue against it.

If people like this idea, I'll do a proof of concept. It shouldn't be
horrific, the templating engine seems pretty extendible in regards to
adding new block tags.

gav

Yuri Baburov

unread,
May 14, 2008, 1:44:49 PM5/14/08
to django-d...@googlegroups.com
Hi, I like to use TEMPLATE_STRING_IF_INVALID with <font
color="red">%s</font>, however such usage is discouraged.
I think that in production mode it's better to put no item into HTML
instead of 500 error in most of cases.
But there might be a method to mail admins somehow for important
fields having broken.
If TEMPLATE_STRING_IF_INVALID is able to show its string, you can make
a code to scream about error or mail admins or whatever. I bet you
don't ever need to patch django for this (maybe just monkeypatch a
bit).
Or, as an alternative, use unit testing to get rid of such problems as
you have experienced. It's considered good practice for dynamic-typed
languages (django templates plus views using them are dynamic-typed,
right?)

--
Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
MSN: bu...@live.com

Jeff Anderson

unread,
May 14, 2008, 4:04:29 PM5/14/08
to django-d...@googlegroups.com
Hello!

Not that I have a vote, but I do have an idea...

Ken Arnold wrote:
> 5. Variable lookups, and everything else, never cause render() to
> fail, but insert an easy-to-catch and easy-to-bypass error string in
> the output.

<snip>
>
> Thoughts?
>

Another option for easy-to-catch and easy-to-bypass error string display
would be to add error strings to a list on the fly (save them for a bit
later).
The template errors/warnings are not reported by default. To get to the
errors, you would use a tag, maybe something like: {% display_errors %}
Another behavior is that it could spit out the errors at the end of the
document generated by the template-- maybe when DEBUG=True? This creates
malformed documents in some cases, but many browsers can/will display
the text anyway.

I could have a template something like this:
<html><head><title>{{ page.title }}</title></head>
<body>
Welcome to my site, {{ user.first_name }}!
<div class="errors">{% display_errors %}</div>
</body>
</html>

that generates a document like this:

<html><head><title></title></head>
<body>
Welcome to my site, !
<div class="errors">Warning: page.title is undefined on line 1 of
index.thtml
Warning: user.first_name is undefined on line 3 of index.thtml</div>
</body>
</html>

My guess that the problem with this implementation is that it'd have to
make two passes to output all the errors that display_errors has to
list. It'd be silly to only report errors that happen before the tag occurs.

Of course some optimizations could be made so that display_errors could
look like: display_errors.as_html, or display_errors.only_debug (to only
display them when DEBUG=True), etc...

Thanks!

Jeff Anderson

signature.asc

Christopher Allan Webber

unread,
May 14, 2008, 6:19:56 PM5/14/08
to django-d...@googlegroups.com
I'm just going to chime in here that a lot of our older apps at our
work use Zope Page Templates.

Largely we've found ZPT pages to be less pleaseant in all regards
*excepting* the fact that they never, ever silently fail. Just as
your code fails when there's a problem, so do your templates. It's
easy to see exactly where the problem is. In django, sometimes it can
be a total mystery. Sometimes you don't even know there's a problem
at all.

Thus I'm hugely +1 on this no-silent-failures bit, whether optional or
not.

John Lenton

unread,
May 15, 2008, 12:03:31 AM5/15/08
to django-d...@googlegroups.com

I'm very much on the +1 to no silent failures ever side, but one thing
that makes it work in ZPT is the |nothing thingie, that allows you to
explicitly ask for silence when needed.

--
John Lenton (jle...@gmail.com) -- Random fortune:
The trouble with a lot of self-made men is that they worship their creator.

alex....@gmail.com

unread,
May 15, 2008, 12:17:11 AM5/15/08
to Django developers
I'd be +1 on this, on the condition that there be some way to supress
errors, something like this.

{% for item in list %}
{{ item.title }}
{% silent %}
{{ item.owner }}
{% endsilent %}
{% endfor %}

On May 14, 11:03 pm, "John Lenton" <jlen...@gmail.com> wrote:
> On Wed, May 14, 2008 at 7:19 PM, Christopher Allan Webber
>
> <cweb...@imagescape.com> wrote:
>
> > I'm just going to chime in here that a lot of our older apps at our
> > work use Zope Page Templates.
>
> > Largely we've found ZPT pages to be less pleaseant in all regards
> > *excepting* the fact that they never, ever silently fail.  Just as
> > your code fails when there's a problem, so do your templates.  It's
> > easy to see exactly where the problem is.  In django, sometimes it can
> > be a total mystery.  Sometimes you don't even know there's a problem
> > at all.
>
> > Thus I'm hugely +1 on this no-silent-failures bit, whether optional or
> > not.
>
> I'm very much on the +1 to no silent failures ever side, but one thing
> that makes it work in ZPT is the |nothing thingie, that allows you to
> explicitly ask for silence when needed.
>
> --
> John Lenton (jlen...@gmail.com) -- Random fortune:

Simon Willison

unread,
May 15, 2008, 3:30:31 AM5/15/08
to Django developers
On May 14, 3:51 pm, Ken Arnold <kenneth.arn...@gmail.com> wrote:
> 4. Other tags and filters, like include, ssi, and truncatewords (from
> a quick scan) that perform some function that could fail, should mark
> that failure very clearly in the output. (Those two currently do, but
> the error string is easy to miss if buried in a mess of other code.)
> 5. Variable lookups, and everything else, never cause render() to
> fail, but insert an easy-to-catch and easy-to-bypass error string in
> the output.

There are a few problems with inserting error output in the template
rather than raising an exception, the most important of which is that
you won't get an HTTP 500 error code so the problem won't be caught in
your server logs. Also, there are a number of situations where the
error output won't be visible in the browser - if it occurs within a
<script> tag or an HTML attribute, for example.

Michael Elsdörfer

unread,
May 15, 2008, 5:15:33 AM5/15/08
to Django developers
> I'd be +1 on this, on the condition that there be some way to supress
> errors, something like this.
>
> {% for item in list %}
> {{ item.title }}
> {% silent %}
> {{ item.owner }}
> {% endsilent %}
> {% endfor %}

That seems very clunky to me. If going down that route, I'd prefer to
either enable filters to catch exceptions, so {{ item.owner|default }}
can work, or maybe use some sort of syntax extension to silence
errors, say for example {{ @ item.owner }}

Michael

Nicolas Lara

unread,
May 15, 2008, 5:23:05 AM5/15/08
to django-d...@googlegroups.com
I've been thinking about this issue, so here are some thoughts:

I like Jeff's idea on inserting the results into the template. I agree
also that the errors in-place pose problems since, as Simon commented,
the errors would not be visible in some cases.

Also the fail silently feature _can_ be _very_useful I've been using
lately a template engine that doesn't have this feature and have been
missing it a lot.

I would say that a throw-errors-by-default policy could be very good
as long as it can be overridden.

How about using something like what mark_safe does for escaping:
so
{{ article.subtitle|or_none }} (naming could be changed: safe? trust?)
would behave as the current template code, failing silently.

If the filter is not used the error would be shown in-place and, if
the user wants to aggregate the errors in only one place in the
template or see errors that are inside <script> tags (among others),
he could use another tag like:
{% aggregate_template_errors %}

that would result in a list of errors and the places they appear in
(maybe even a snippet of the failing block of the template), removing
the errors that were to be shown in place.

Also this behaviour should change to the always-fail-silently one when
DEBUG=false.

To me this approach is very clean and would keep the backward
compatibility on production sites. Development sites would probably
need some changes to adjust to the new behaviour, but, come on!, they
are still on development!, changes are suposed to happen :)

Well, there are my two cents, let me know what you think,

--
Nicolas Lara

Derek Hoy

unread,
May 15, 2008, 5:24:23 AM5/15/08
to django-d...@googlegroups.com
I sometimes return an 'error' string from my own tags when it's
important to see a problem.

One way of making that more elegant would be to make an explicit
MustNotBeSilencedException that a tag could use for error checking.

The template handling code would ignore all other exceptions.

Derek

phillc

unread,
May 15, 2008, 10:28:09 AM5/15/08
to Django developers
i like the filter idea, but would prefer the default to be required,
and a filter to specify when something is not required (that might be
harder to push because of backwards incompatability)

i dont agree with the setting to be based on debug.
last thing i want is my test behavior being different from my
production.

Honza Král

unread,
May 15, 2008, 1:18:35 PM5/15/08
to django-d...@googlegroups.com
I agree that silently failing is useful for var lookups,not as much for tags..
how about having a TemplateDebugException,that would be silenced in
production, availible for use in tags and some special syntax for var
lookups,like

{{ var.key|filter or '' }} or just
{{ var.key|filter '' }} or anything else

that way we can catch exceptions without abusing filters...

--
Sent from Gmail for mobile | mobile.google.com

Honza Král
E-Mail: Honza...@gmail.com
ICQ#: 107471613
Phone: +420 606 678585

Thomas Guettler

unread,
May 16, 2008, 2:25:04 AM5/16/08
to django-d...@googlegroups.com
Simon Willison schrieb:

>
> There are a few problems with inserting error output in the template
> rather than raising an exception, ...
I use this to raise an exception:

{{{
# settings.py
if DEBUG:
TEMPLATE_STRING_IF_INVALID = InvalidVarException()
}}}

This raises an exception, if a variable is missing.

See http://www.djangosnippets.org/snippets/646/

Unfortunately TEMPLATE_STRING_IF_INVALID is not used in all places:
e.g. Loops: http://code.djangoproject.com/ticket/6766

Thomas

--
Thomas Guettler, http://www.thomas-guettler.de/
E-Mail: guettli (*) thomas-guettler + de

zellyn

unread,
May 16, 2008, 8:28:48 AM5/16/08
to Django developers
+1 on no silent errors by default.

Tying behaviour to the DEBUG setting is wrong: if you're building a
template with optional Titles, you'd want to be able to test it in
your debug environment with Titles both present and missing.

I know creating more syntax is evil, but how about {{ post.title }}
versus {{ ? post.title }} (vaguely regexy) or {{ post.title or '' }}
(pythony)? At least those won't change the regex that pulls out {{ }}
blocks.

Zellyn Hunter
ajc.com

Peter Rowell

unread,
May 17, 2008, 11:14:36 AM5/17/08
to Django developers
Personally, I prefer fireworks when a variable is not set.

Here's yet another possibility, just a variant on current code:
TEMPLATE_STRING_IF_INVALID = "<span class='template-var-error'>%
(expression)s: %(error)s</span>"
The above would be filled in by _resolve_lookup with appropriate
values.

Then you have a style:
template-var-error {
display:none; /* or inline or block */
color: red;
background-color: yellow;
border: solid 1px red;
}

This will display a nice error message for normal string use, but blow
up the template in places where a URL was expected.

E.g., <form action="<span class='template-var-error'>%(expression)s: %
(error)s</span>"> will probably fail in a fairly obvious way.

Just a thought.

James Bennett

unread,
May 18, 2008, 12:30:05 AM5/18/08
to django-d...@googlegroups.com
On Wed, May 14, 2008 at 8:58 AM, Simon Willison <si...@simonwillison.net> wrote:
> Silent errors are bad. If we were to remove them, how much of a
> negative impact would it have on the existing user base?

The impression I get is that a lot of people rely on silent *variable*
failure, but very few rely on silent *tag* failure. In fact, most
real-world custom template tags I've seen are wired up to raise errors
quite loudly, and the few times I've tried to write tags which fail
silently it's been a laborious process that results in much more
brittle code.

And, really, variables are the big thing that the current behavior
helps: it's really really nice to be able to do boolean tests on
things that might not exist, and trust that the test evaluates False
instead of, say, raising a KeyError because you asked about something
that isn't in the context dictionary.

So, personally, I'd vote for keeping the current behavior with respect
to variables, and rewriting any built-in tags to raise exceptions when
you do something wrong.


--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

alex....@gmail.com

unread,
May 18, 2008, 11:54:36 AM5/18/08
to Django developers
Another issue(related to error raising in templates), is that when an
error propagates inside a loop the error page highlights the error as
being in the {% for %} tag, which is often confusing, I'm not sure
what causes this, since the traceback correctly highlights the actual
issue in question.

Steven Armstrong

unread,
May 18, 2008, 12:45:48 PM5/18/08
to django-d...@googlegroups.com
James Bennett wrote on 05/18/08 06:30:

+1

What I personally would like to see is that such errors where logged
somewhere. I know this came up before, and that the django devs, for
whatever reasons, think it's not necessary.

But something like:

try:
whatever
except SomeTemplateError, e:
logger.debug('Template Error: %s', e)

Would IMHO be the most elegant solution.

Jacob Kaplan-Moss

unread,
May 20, 2008, 10:45:16 AM5/20/08
to django-d...@googlegroups.com
On Sat, May 17, 2008 at 11:30 PM, James Bennett <ubern...@gmail.com> wrote:
> The impression I get is that a lot of people rely on silent *variable*
> failure, but very few rely on silent *tag* failure. In fact, most
> real-world custom template tags I've seen are wired up to raise errors
> quite loudly, and the few times I've tried to write tags which fail
> silently it's been a laborious process that results in much more
> brittle code.

Well said. I can't see making ``{{ foo.bar.baz }}`` fail loudly --
it's just too big a change. It especially sucks when ``foo`` or
``bar`` is a dynamically-constructed dictionary with variable keys.

I think taking a close look at built-in *tags*, though, is a good idea
-- in general, tags should fail loudly. There are exceptions, of
course; ``{% if dict.somekey %}`` is a common idiom which translates
to something like ``if dict.has_key('somekey') and dict.somekey`` --
this is good.

A final note: if you want loud variable failures, it's a pretty
trivial task to write a template tag that echoes a variable or raises
an exception; you could then use ``{% require foo.bar.baz %}`` instead
of ``{{ foo.bar.baz }}``. I'll leave the actual implementation up to
the intrepid reader; it's just a few lines of code.

Jacob

graham_king

unread,
May 20, 2008, 3:54:46 PM5/20/08
to Django developers
Making {{ myval }} fail loudy would break the admin app. Setting
TEMPLATE_STRING_IF_INVALID to anything other than '' also breaks it.

Here's an example: http://code.djangoproject.com/ticket/5532
This ticket has all the details: http://code.djangoproject.com/ticket/3579

Will this be fixed in newforms-admin?

Yuri Baburov

unread,
May 20, 2008, 4:55:34 PM5/20/08
to django-d...@googlegroups.com
I can add newer patch if anyone interested.

--

Curtis

unread,
May 20, 2008, 11:27:10 PM5/20/08
to Django developers

Has anyone considered using Python's 'warnings' module? It seems like
it might be the perfect fit for this problem.

For example, if the appropriate warn() calls were added to the
templating system, by default, problems would be sent to sys.stderr.
By setting up a warnings filter in (for e.g. in settings.py), we could
define which warnings ("errors") threw exceptions -- a fail loudly
solution. And finally, we could (I'm debating the usefulness of
this), create a 'showwarnings' tag which would format the current
warnings in the template.

This, at least to me, seems like it could solve most people's
problems.

Cheers,

-Curtis

Patryk Zawadzki

unread,
May 21, 2008, 4:50:46 AM5/21/08
to django-d...@googlegroups.com
On Wed, May 21, 2008 at 5:27 AM, Curtis <curtis....@gmail.com> wrote:
>
>
> Has anyone considered using Python's 'warnings' module? It seems like
> it might be the perfect fit for this problem.
>
> For example, if the appropriate warn() calls were added to the
> templating system, by default, problems would be sent to sys.stderr.

With the little exception that writing to stdout or stderr from a
fcgi/wsgi application will kill your application server with a nice
"broken pipe" when deployed on production :)

--
Patryk Zawadzki
PLD Linux Distribution

Graham King

unread,
May 21, 2008, 11:58:32 AM5/21/08
to django-d...@googlegroups.com
'warnings' sounds like a subset of 'logging'.

In a similar thread (about template tags and filters failing
silently) two years ago Simon Willison (who started this thread) said:

"We really need an official Django logging framework so stuff like
this can be logged"
http://groups.google.com/group/django-developers/browse_thread/thread/40adac6370fc195c/b1656b8e0c036c04

Maybe the right answer here is simply logging an info (or warning)
message when a template can't find a value. Steven Armstrong has
already mentioned it in this thread.
And if Django had logging, we could have a SQL log, and I wouldn't
have to start all my projects by setting up a logger, a SQL logging
middleware, and an audit log of object create/update/delete.
If there is support from on high for putting logging into Django, I'm
more than happy to make the code changes.

And I'm +1 on making tags fail loudly.

2008/5/21 Patryk Zawadzki <pat...@gmail.com>:

Don Spaulding II

unread,
May 21, 2008, 1:59:03 PM5/21/08
to django-d...@googlegroups.com


Graham King wrote:
 And if Django had logging, we could have a SQL log, and I wouldn't
have to start all my projects by setting up a logger, a SQL logging
middleware, and an audit log of object create/update/delete.
I trust you've seen the django-logging project on c.g.c?

http://code.google.com/p/django-logging/

Gary Wilson Jr.

unread,
Jun 10, 2008, 3:15:43 PM6/10/08
to django-d...@googlegroups.com
Jacob Kaplan-Moss wrote:
> On Sat, May 17, 2008 at 11:30 PM, James Bennett <ubern...@gmail.com> wrote:
>> The impression I get is that a lot of people rely on silent *variable*
>> failure, but very few rely on silent *tag* failure. In fact, most
>> real-world custom template tags I've seen are wired up to raise errors
>> quite loudly, and the few times I've tried to write tags which fail
>> silently it's been a laborious process that results in much more
>> brittle code.
>
> Well said. I can't see making ``{{ foo.bar.baz }}`` fail loudly --
> it's just too big a change. It especially sucks when ``foo`` or
> ``bar`` is a dynamically-constructed dictionary with variable keys.

Yes, probably too big a change to make ``{{ foo.bar.baz }}`` fail loudly
at this point (even though there are things like the default filter and
the firstof tag that could facilitate such a change).

I would, however, be in favor for making the exception-catching a bit
smarter here so that we don't suppress exceptions raised by a called
method. For example, I'm ok with:

{{ foo.calculate_number }}

failing silently if no calculate_number attribute/method exists for foo,
but if calculate_number is a method and happens to raise an exception
when called, I want that to bubble up and fail loudly. Otherwise,
hunting down the error becomes more of a chore. Besides, the motivation
behind the silent behavior seems to be more for missing attributes.

> I think taking a close look at built-in *tags*, though, is a good idea
> -- in general, tags should fail loudly. There are exceptions, of
> course; ``{% if dict.somekey %}`` is a common idiom which translates
> to something like ``if dict.has_key('somekey') and dict.somekey`` --
> this is good.

I also agree that, in many instances, tags should fail loudly, and that
these types of failures need to be looked at on a tag by tag basis. The
question then becomes, do we want to always raise these exceptions or do
we want to only raise them if settings.TEMPLATE_DEBUG is True?

Gary

Reply all
Reply to author
Forward
0 new messages