Restored template error handling for Django 1.9 and newer.
This commit is contained in:
parent
8755ce3b64
commit
0a2f65df9e
|
@ -151,14 +151,23 @@ class DjangoClient(Client):
|
|||
|
||||
if kwargs.get('exc_info'):
|
||||
exc_value = kwargs['exc_info'][1]
|
||||
# As of r16833 (Django) all exceptions may contain a ``django_template_source`` attribute (rather than the
|
||||
# legacy ``TemplateSyntaxError.source`` check) which describes template information.
|
||||
if hasattr(exc_value, 'django_template_source') or ((isinstance(exc_value, TemplateSyntaxError) and
|
||||
isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], Origin))):
|
||||
source = getattr(exc_value, 'django_template_source', getattr(exc_value, 'source', None))
|
||||
# As of r16833 (Django) all exceptions may contain a
|
||||
# ``django_template_source`` attribute (rather than the legacy
|
||||
# ``TemplateSyntaxError.source`` check) which describes
|
||||
# template information. As of Django 1.9 or so the new
|
||||
# template debug thing showed up.
|
||||
if hasattr(exc_value, 'django_template_source') or \
|
||||
((isinstance(exc_value, TemplateSyntaxError) and
|
||||
isinstance(getattr(exc_value, 'source', None),
|
||||
(tuple, list)) and
|
||||
isinstance(exc_value.source[0], Origin))) or \
|
||||
hasattr(exc_value, 'template_debug'):
|
||||
source = getattr(exc_value, 'django_template_source',
|
||||
getattr(exc_value, 'source', None))
|
||||
debug = getattr(exc_value, 'template_debug', None)
|
||||
if source is None:
|
||||
self.logger.info('Unable to get template source from exception')
|
||||
data.update(get_data_from_template(source))
|
||||
data.update(get_data_from_template(source, debug))
|
||||
|
||||
result = super(DjangoClient, self).capture(event_type, **kwargs)
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ raven.contrib.django.utils
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
|
@ -20,21 +21,31 @@ def linebreak_iter(template_source):
|
|||
yield len(template_source) + 1
|
||||
|
||||
|
||||
def get_data_from_template(source):
|
||||
origin, (start, end) = source
|
||||
template_source = origin.reload()
|
||||
def get_data_from_template(source, debug=None):
|
||||
if debug is not None:
|
||||
start = debug['start']
|
||||
end = debug['end']
|
||||
source_lines = debug['source_lines']
|
||||
lineno = debug['line']
|
||||
filename = debug['name']
|
||||
culprit = filename.split('/templates/')[-1]
|
||||
elif source:
|
||||
origin, (start, end) = source
|
||||
filename = culprit = getattr(origin, 'loadname', None)
|
||||
template_source = origin.reload()
|
||||
lineno = None
|
||||
upto = 0
|
||||
source_lines = []
|
||||
for num, next in enumerate(linebreak_iter(template_source)):
|
||||
if start >= upto and end <= next:
|
||||
lineno = num
|
||||
source_lines.append(template_source[upto:next])
|
||||
upto = next
|
||||
|
||||
lineno = None
|
||||
upto = 0
|
||||
source_lines = []
|
||||
for num, next in enumerate(linebreak_iter(template_source)):
|
||||
if start >= upto and end <= next:
|
||||
lineno = num
|
||||
source_lines.append(template_source[upto:next])
|
||||
upto = next
|
||||
|
||||
if not source_lines or lineno is None:
|
||||
return {}
|
||||
if not source_lines or lineno is None:
|
||||
return {}
|
||||
else:
|
||||
raise TypeError('Source or debug needed')
|
||||
|
||||
pre_context = source_lines[max(lineno - 3, 0):lineno]
|
||||
post_context = source_lines[(lineno + 1):(lineno + 4)]
|
||||
|
@ -42,14 +53,14 @@ def get_data_from_template(source):
|
|||
|
||||
return {
|
||||
'template': {
|
||||
'filename': getattr(origin, 'loadname', None),
|
||||
'abs_path': origin.name,
|
||||
'filename': os.path.basename(filename),
|
||||
'abs_path': filename,
|
||||
'pre_context': pre_context,
|
||||
'context_line': context_line,
|
||||
'lineno': lineno,
|
||||
'post_context': post_context,
|
||||
},
|
||||
'culprit': getattr(origin, 'loadname', None),
|
||||
'culprit': culprit,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1 +1,20 @@
|
|||
{% invalid template tag %}
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
{% invalid template tag %}
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
|
|
|
@ -319,9 +319,6 @@ class DjangoClientTest(TestCase):
|
|||
assert event['culprit'].startswith('django.shortcuts in ')
|
||||
self.raven.include_paths = include_paths
|
||||
|
||||
# This is broken as of recently. It only works on older Django
|
||||
# versions?
|
||||
@pytest.mark.xfail
|
||||
def test_template_name_as_view(self):
|
||||
self.assertRaises(TemplateSyntaxError, self.client.get, reverse('sentry-template-exc'))
|
||||
|
||||
|
|
Loading…
Reference in New Issue