Exceptions caught by the "include" template tag make it hard to rely on tests

827 views
Skip to first unread message

Sylvain Fankhauser

unread,
Jun 9, 2016, 8:37:34 AM6/9/16
to django-d...@googlegroups.com
Hi all,

I got really frustrated today trying to understand why a bug could get past my test suite but fail in my dev environment. Finally Baptiste Mispelon pointed me to the include template tag documentation:

If the included template causes an exception while it’s rendered (including if it’s missing or has syntax errors), the behavior varies depending on the template engine's debug option (if not set, this option defaults to the value of DEBUG). When debug mode is turned on, an exception like TemplateDoesNotExist or TemplateSyntaxError will be raised. When debug mode is turned off, {% include %} logs a warning to the django.template logger with the exception that happens while rendering the included template and returns an empty string.

That's a real problem when running tests, because since the exception is just silenced your tests will still pass although there was actually some error in your code. The current way to deal with this is, I guess, to set the template engine DEBUG option to True in the test environment but that doesn't seem right to me.

I don't have a solution right now and I know this would be a big backwards incompatible change and the chances for this to change are abysmally low. But maybe we could just add an option for that (to make exceptions pop out of the include tag), set its default value to match the current behaviour, and change it with a clear deprecation plan?

Cheers,
Sylvain

Sylvain Fankhauser

unread,
Jul 11, 2016, 4:06:11 AM7/11/16
to django-d...@googlegroups.com
Hi,

I'm bringing this back to the table since I can't believe I'm the only one to find this behaviour weird and possibly dangerous. I'd really be interested in getting your opinion on this!

Thanks,
Sylvain

Tim Graham

unread,
Jul 11, 2016, 1:56:34 PM7/11/16
to Django developers (Contributions to Django itself)
Found in another thread [0]: "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."

And another [1]: "The broad reasoning is that a partial page rendering is preferable to a 500 error when rendering a template. This is driven by production requirements -- the end user shouldn't ever see a 500 error."

As for me as a developer, I'd support removing the exception silencing that {% include %} does so that errors appear alongside any other exceptions (e.g. in Sentry) rather than in the django.template logger (that logging was added in Django 1.9).

[0] https://groups.google.com/d/msg/django-developers/8yMzgEWsLl4/H7ITMVMkZcwJ
[1] https://groups.google.com/d/msg/django-developers/KpDS2tWLp7U/y7zli4P79nkJ

Florian Apolloner

unread,
Jul 11, 2016, 3:45:31 PM7/11/16
to Django developers (Contributions to Django itself)


On Monday, July 11, 2016 at 7:56:34 PM UTC+2, Tim Graham wrote:
As for me as a developer, I'd support removing the exception silencing that {% include %} does so that errors appear alongside any other exceptions (e.g. in Sentry) rather than in the django.template logger (that logging was added in Django 1.9).

Dito, most tags should error out where it makes sense, but not sure if we can easily change that :(

Shai Berger

unread,
Jul 11, 2016, 6:17:58 PM7/11/16
to django-d...@googlegroups.com
It must be opt-in; now that we have template engines and they're configured in
dictionaries, we have plenty of room for that, though.

Another option to consider is make them error out only under the test-client.

My 2 cents,
Shai.

Tim Graham

unread,
Jul 11, 2016, 6:36:11 PM7/11/16
to Django developers (Contributions to Django itself)
Has anyone relied on the exception silencing behavior as a "feature" when using {% include %}? It doesn't seem that's really possible given you can't use that feature when template.debug=True. Thus, the current behavior doesn't strike me as a reasonable default. Perhaps we can change it after a deprecation. Does anyone really want an alternative to keep the silencing behavior?

From a user's perspective, I think it's more confusing to see a partial and possibly broken page (but not necessarily knowing that it's broken) than an error page.

Preston Timmons

unread,
Jul 12, 2016, 6:34:59 PM7/12/16
to Django developers (Contributions to Django itself)
From my experience the silent failure is more confusing than helpful. I like Jinja's approach here that enables missing templates to be explicitly silenced when desired, i.e.:

{% include "sidebar.html" ignore missing %}

Preston

Sergei Maertens

unread,
Sep 3, 2016, 8:03:10 PM9/3/16
to Django developers (Contributions to Django itself)
No, this is actually one of the reasons I keep recommending people to use inclusion tags as opposed to the {% include %} tag, and I see the same recommendation/reasoning in the IRC channel.

Jon Dufresne

unread,
Sep 4, 2016, 12:27:58 PM9/4/16
to django-d...@googlegroups.com
> Has anyone relied on the exception silencing behavior as a "feature" when using {% include %}?

Not here.

+1 on deprecating the silencing behavior.

I have created a ticket [0] and PR [1] so others may get a sense of the bigger picture change and how it could affect Django. Feedback welcome.

More generally, I find the template engine's behavior of replacing exceptions with an empty string to cause more bugs than it prevents. In my experience, loud errors will more likely be caught during development, unit tests, and manual testing.

[0] https://code.djangoproject.com/ticket/27175
[1] https://github.com/django/django/pull/7208

Reply all
Reply to author
Forward
0 new messages