blob: 9fe698b576b213098fb7affb2ed317c7d9a84951 [file] [log] [blame]
Armin Ronacher07bc6842008-03-31 14:18:49 +02001# -*- coding: utf-8 -*-
2"""
Armin Ronacher26c0f512008-04-17 11:16:01 +02003 jinja2.exceptions
4 ~~~~~~~~~~~~~~~~~
Armin Ronacher07bc6842008-03-31 14:18:49 +02005
6 Jinja exceptions.
7
Armin Ronacher55494e42010-01-22 09:41:48 +01008 :copyright: (c) 2010 by the Jinja Team.
Armin Ronacher07bc6842008-03-31 14:18:49 +02009 :license: BSD, see LICENSE for more details.
10"""
Alex Moregae29c84c2013-05-18 15:35:46 +030011import sys
Thomas Waldmanne0003552013-05-17 23:52:14 +020012import six
Daniel Neuhäuserd0708db2013-05-18 12:52:40 +020013from six.moves import map
Armin Ronacher07bc6842008-03-31 14:18:49 +020014
15
Armin Ronachere791c2a2008-04-07 18:39:54 +020016class TemplateError(Exception):
Armin Ronacher9a822052008-04-17 18:44:07 +020017 """Baseclass for all template errors."""
18
Alex Moregae29c84c2013-05-18 15:35:46 +030019 if sys.version_info[0] < 3:
20 def __init__(self, message=None):
Armin Ronacher1d021082009-02-19 20:07:13 +010021 if message is not None:
Alex Moregae29c84c2013-05-18 15:35:46 +030022 message = six.text_type(message).encode('utf-8')
23 Exception.__init__(self, message)
24
25 @property
26 def message(self):
27 if self.args:
28 message = self.args[0]
29 if message is not None:
30 return message.decode('utf-8', 'replace')
31
32 else:
33 @property
34 def message(self):
35 if self.args:
36 message = self.args[0]
37 if message is not None:
38 return message
Armin Ronacher1d021082009-02-19 20:07:13 +010039
Armin Ronacher9a822052008-04-17 18:44:07 +020040
Armin Ronacher07bc6842008-03-31 14:18:49 +020041class TemplateNotFound(IOError, LookupError, TemplateError):
Armin Ronacher9a822052008-04-17 18:44:07 +020042 """Raised if a template does not exist."""
Armin Ronacher07bc6842008-03-31 14:18:49 +020043
Armin Ronacher31bbd9e2010-01-14 00:41:30 +010044 # looks weird, but removes the warning descriptor that just
45 # bogusly warns us about message being deprecated
46 message = None
47
48 def __init__(self, name, message=None):
49 IOError.__init__(self)
50 if message is None:
51 message = name
52 self.message = message
Armin Ronacher07bc6842008-03-31 14:18:49 +020053 self.name = name
Armin Ronacher31bbd9e2010-01-14 00:41:30 +010054 self.templates = [name]
55
Armin Ronacher31bbd9e2010-01-14 00:41:30 +010056 def __str__(self):
57 return self.message.encode('utf-8')
58
Armin Ronacheracbd4082010-02-10 00:07:43 +010059 # unicode goes after __str__ because we configured 2to3 to rename
60 # __unicode__ to __str__. because the 2to3 tree is not designed to
61 # remove nodes from it, we leave the above __str__ around and let
62 # it override at runtime.
Armin Ronacher790b8a82010-02-10 00:05:46 +010063 def __unicode__(self):
64 return self.message
65
Armin Ronacher31bbd9e2010-01-14 00:41:30 +010066
67class TemplatesNotFound(TemplateNotFound):
68 """Like :class:`TemplateNotFound` but raised if multiple templates
69 are selected. This is a subclass of :class:`TemplateNotFound`
70 exception, so just catching the base exception will catch both.
71
72 .. versionadded:: 2.2
73 """
74
75 def __init__(self, names=(), message=None):
76 if message is None:
Simon Sapin52c88fb2011-12-03 13:05:08 +010077 message = u'none of the templates given were found: ' + \
Thomas Waldmann7d295622013-05-18 00:06:22 +020078 u', '.join(map(six.text_type, names))
Armin Ronacher31bbd9e2010-01-14 00:41:30 +010079 TemplateNotFound.__init__(self, names and names[-1] or None, message)
80 self.templates = list(names)
Armin Ronacher07bc6842008-03-31 14:18:49 +020081
82
Armin Ronacher68f77672008-04-17 11:50:39 +020083class TemplateSyntaxError(TemplateError):
Armin Ronacher9a822052008-04-17 18:44:07 +020084 """Raised to tell the user that there is a problem with the template."""
Armin Ronacher07bc6842008-03-31 14:18:49 +020085
Armin Ronacher7f15ef82008-05-16 09:11:39 +020086 def __init__(self, message, lineno, name=None, filename=None):
Armin Ronacher1d021082009-02-19 20:07:13 +010087 TemplateError.__init__(self, message)
Armin Ronacher07bc6842008-03-31 14:18:49 +020088 self.lineno = lineno
Armin Ronacher7f15ef82008-05-16 09:11:39 +020089 self.name = name
Armin Ronacheraaf010d2008-05-01 13:14:30 +020090 self.filename = filename
Armin Ronacherccae0552008-10-05 23:08:58 +020091 self.source = None
Armin Ronacherccae0552008-10-05 23:08:58 +020092
Armin Ronacherd416a972009-02-24 22:58:00 +010093 # this is set to True if the debug.translate_syntax_error
94 # function translated the syntax error into a new traceback
95 self.translated = False
96
Armin Ronacher790b8a82010-02-10 00:05:46 +010097 def __str__(self):
Thomas Waldmann7d295622013-05-18 00:06:22 +020098 s = self.__unicode__()
99 return s if six.PY3 else s.encode('utf-8')
Armin Ronacher790b8a82010-02-10 00:05:46 +0100100
Armin Ronacherccae0552008-10-05 23:08:58 +0200101 def __unicode__(self):
Armin Ronacherd416a972009-02-24 22:58:00 +0100102 # for translated errors we only return the message
103 if self.translated:
Armin Ronacher0d242be2010-02-10 01:35:13 +0100104 return self.message
Armin Ronacherd416a972009-02-24 22:58:00 +0100105
106 # otherwise attach some stuff
Armin Ronacherccae0552008-10-05 23:08:58 +0200107 location = 'line %d' % self.lineno
108 name = self.filename or self.name
109 if name:
110 location = 'File "%s", %s' % (name, location)
111 lines = [self.message, ' ' + location]
112
113 # if the source is set, add the line to the output
114 if self.source is not None:
115 try:
116 line = self.source.splitlines()[self.lineno - 1]
117 except IndexError:
118 line = None
119 if line:
120 lines.append(' ' + line.strip())
121
122 return u'\n'.join(lines)
123
Armin Ronacher07bc6842008-03-31 14:18:49 +0200124
Armin Ronacher53042292008-04-26 18:30:19 +0200125class TemplateAssertionError(TemplateSyntaxError):
Armin Ronacher9a822052008-04-17 18:44:07 +0200126 """Like a template syntax error, but covers cases where something in the
127 template caused an error at compile time that wasn't necessarily caused
Armin Ronacherf3c35c42008-05-23 23:18:14 +0200128 by a syntax error. However it's a direct subclass of
129 :exc:`TemplateSyntaxError` and has the same attributes.
Armin Ronacher9a822052008-04-17 18:44:07 +0200130 """
Armin Ronachere791c2a2008-04-07 18:39:54 +0200131
Armin Ronachere791c2a2008-04-07 18:39:54 +0200132
Armin Ronacher07bc6842008-03-31 14:18:49 +0200133class TemplateRuntimeError(TemplateError):
Armin Ronacherf3c35c42008-05-23 23:18:14 +0200134 """A generic runtime error in the template engine. Under some situations
135 Jinja may raise this exception.
136 """
Benjamin Wieganda3152742008-04-28 18:07:52 +0200137
138
Armin Ronacherf3c35c42008-05-23 23:18:14 +0200139class UndefinedError(TemplateRuntimeError):
140 """Raised if a template tries to operate on :class:`Undefined`."""
141
142
143class SecurityError(TemplateRuntimeError):
144 """Raised if a template tries to do something insecure if the
145 sandbox is enabled.
146 """
147
148
149class FilterArgumentError(TemplateRuntimeError):
Benjamin Wieganda3152742008-04-28 18:07:52 +0200150 """This error is raised if a filter was called with inappropriate
151 arguments
152 """