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
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/
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
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
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.
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 }}
-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
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
--
Best regards, Yuri V. Baburov, ICQ# 99934676, Skype: yuri.baburov,
MSN: bu...@live.com
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
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 (jle...@gmail.com) -- Random fortune:
The trouble with a lot of self-made men is that they worship their creator.
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
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
{{ 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
{{{
# 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
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."
+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.
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
--
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
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>:
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.
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