Opened 9 years ago
Closed 9 years ago
#24960 closed Bug (fixed)
Blank pages due to {{ block.super }}
Reported by: | Sven R. Kunze | Owned by: | nobody |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Normal | Keywords: | block.super blank pages |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | yes |
Description (last modified by )
When using {{ block.super }}, it behaves like a normal variable which leads to the following issue:
As soon as the block.super raises (e.g.) a UnicodeDecodeError, {{ block.super }} evaluates to an empty string.
When using {{ block.super }} in cascading base templates, this frequently leads to blank pages which are hard to debug.
Change History (13)
comment:1 by , 9 years ago
Description: | modified (diff) |
---|---|
Keywords: | UnicodeDecodeError added; UnicodeEncodeError removed |
Summary: | {{ block.super }} hides UnicodeEncodeErrors → {{ block.super }} hides UnicodeDecodeErrors |
comment:2 by , 9 years ago
Description: | modified (diff) |
---|---|
Keywords: | blank pages added; UnicodeDecodeError removed |
Summary: | {{ block.super }} hides UnicodeDecodeErrors → Blank pages due to {{ block.super }} |
comment:3 by , 9 years ago
Resolution: | → worksforme |
---|---|
Status: | new → closed |
comment:4 by , 9 years ago
Resolution: | worksforme |
---|---|
Status: | closed → new |
We created a minimal working example: https://gist.github.com/srkunze/613f26697ab81535fa11
t1.html, t2.html << base templates
t3.html << example page using failing tag
t4.html << example page using failing variable
test_tag.py << example tag; you need to put this file into a working templatestag folder in a working Django app
test.py << run this to see the results
test_output.txt << test output rendering t3.html and t4.html
As you can see, t3.html and t4.html yields different results, although the only difference is the usage of tags vs. variables.
The reason for this is the {{ block.super }} variable that returns just an empty string
comment:5 by , 9 years ago
Thanks for the example code, however, when I put those render_to_string()
calls into views like this:
def t3(request): return render_to_string('t3.html') def t4(request): return render_to_string('t4.html', {'error': Error})
I get a yellow debug page in both cases. What behavior do you see? Do you have DEBUG=True
? Are you testing with master or some older version of Django?
comment:6 by , 9 years ago
Are you sure that render_to_string(...) works as intended here? Should a view not return a HttpResponse?
We used Django 1.6. We upgraded to Django 1.8 and it seems as if the error is returned properly now.
We looked into the corresponding Django source code and found that Django catches more errors as before and re-raises them. That approach seems a bit error-prone especially when using custom exceptions.
Don't you think that a check whether a context variable is callable/has attribute/has dictionary key should be handled not by trial-and-error but by a check-before-do?
comment:7 by , 9 years ago
Yes, my usage of render_to_string()
isn't proper, but it seemed enough to test the code you provided.
I'm not following what you are saying now. Django 1.8 fixes the original issue but there's another issue there? Please clarify what behavior you are seeing and what the expected behavior is.
comment:8 by , 9 years ago
In Django 1.6, render_to_string does not work. Maybe, in Django 1.8 this is also another convenience layer.
Well, not sure if Django 1.8 fixes the original issue. Infact, when programming, we simply do not know which errors might occur. So, just because Django re-raises TypeErrors now, does not necessarily mean that we cover all cases (all types of errors).
As soon as somebody raises another exception that is not covered, we are going to see a blank page again. So, our suggestion was: why not check if the given context variable might work in the first place?
Right now, all Django versions just call the variables, do the attribute, do the list access etc. So, we mix up both cases:
- wrong access or
- internal error when evaluating
cf. https://github.com/django/django/blob/1.8.2/django/template/base.py#L804
We actually do not want an ever-growing list of Errors (TypeError, AttributeError, KeyError, ValueError, IndexError -- as you can see in base.py) but a clean long-lasting solution.
For instance, Python provides the function 'hasattr' which can be used to check whether an object has a certain attribute or not. The same goes for list access and function calls.
comment:9 by , 9 years ago
For reference, I bisected the fix down to 28a571348bca9c5a3c137e495e7d3c9349a5bd56 which was a fix for #20745.
comment:10 by , 9 years ago
I still haven't managed to reproduce the "blank page" issue. Could you given an example?
comment:11 by , 9 years ago
Thanks @bmispelon. TypeError was just a quick example. See comment:8, we actually do not appreciate the trial-and-error approach that will lead to an ever-growing except list.
I inspected the commit and it seems it works as intended. I will come back tomorrow and tell you want we find out and may close this issue.
Thanks so far for your support on this.
comment:13 by , 9 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
We further investigated the issue. We found that with an upgrade to 1.8, we might resolve the issue of empty {{ block.super }}.
However, we might consider opening another issue for the inconsistencies of variable resolution. We still would prefer a check-if-possible approach instead of try-and-fail.
I couldn't reproduce this. We'll need more details such as a sample project that reproduces the error. I got a yellow "debug page" when
DEBUG=True
and a 500 error page whenDEBUG=False
. Thanks.