1# -*- coding: utf-8 -*-
2"""
3    jinja2.exceptions
4    ~~~~~~~~~~~~~~~~~
5
6    Jinja exceptions.
7
8    :copyright: (c) 2010 by the Jinja Team.
9    :license: BSD, see LICENSE for more details.
10"""
11
12
13class TemplateError(Exception):
14    """Baseclass for all template errors."""
15
16    def __init__(self, message=None):
17        if message is not None:
18            message = unicode(message).encode('utf-8')
19        Exception.__init__(self, message)
20
21    @property
22    def message(self):
23        if self.args:
24            message = self.args[0]
25            if message is not None:
26                return message.decode('utf-8', 'replace')
27
28
29class TemplateNotFound(IOError, LookupError, TemplateError):
30    """Raised if a template does not exist."""
31
32    # looks weird, but removes the warning descriptor that just
33    # bogusly warns us about message being deprecated
34    message = None
35
36    def __init__(self, name, message=None):
37        IOError.__init__(self)
38        if message is None:
39            message = name
40        self.message = message
41        self.name = name
42        self.templates = [name]
43
44    def __str__(self):
45        return self.message.encode('utf-8')
46
47    # unicode goes after __str__ because we configured 2to3 to rename
48    # __unicode__ to __str__.  because the 2to3 tree is not designed to
49    # remove nodes from it, we leave the above __str__ around and let
50    # it override at runtime.
51    def __unicode__(self):
52        return self.message
53
54
55class TemplatesNotFound(TemplateNotFound):
56    """Like :class:`TemplateNotFound` but raised if multiple templates
57    are selected.  This is a subclass of :class:`TemplateNotFound`
58    exception, so just catching the base exception will catch both.
59
60    .. versionadded:: 2.2
61    """
62
63    def __init__(self, names=(), message=None):
64        if message is None:
65            message = u'non of the templates given were found: ' + \
66                      u', '.join(map(unicode, names))
67        TemplateNotFound.__init__(self, names and names[-1] or None, message)
68        self.templates = list(names)
69
70
71class TemplateSyntaxError(TemplateError):
72    """Raised to tell the user that there is a problem with the template."""
73
74    def __init__(self, message, lineno, name=None, filename=None):
75        TemplateError.__init__(self, message)
76        self.lineno = lineno
77        self.name = name
78        self.filename = filename
79        self.source = None
80
81        # this is set to True if the debug.translate_syntax_error
82        # function translated the syntax error into a new traceback
83        self.translated = False
84
85    def __str__(self):
86        return unicode(self).encode('utf-8')
87
88    # unicode goes after __str__ because we configured 2to3 to rename
89    # __unicode__ to __str__.  because the 2to3 tree is not designed to
90    # remove nodes from it, we leave the above __str__ around and let
91    # it override at runtime.
92    def __unicode__(self):
93        # for translated errors we only return the message
94        if self.translated:
95            return self.message
96
97        # otherwise attach some stuff
98        location = 'line %d' % self.lineno
99        name = self.filename or self.name
100        if name:
101            location = 'File "%s", %s' % (name, location)
102        lines = [self.message, '  ' + location]
103
104        # if the source is set, add the line to the output
105        if self.source is not None:
106            try:
107                line = self.source.splitlines()[self.lineno - 1]
108            except IndexError:
109                line = None
110            if line:
111                lines.append('    ' + line.strip())
112
113        return u'\n'.join(lines)
114
115
116class TemplateAssertionError(TemplateSyntaxError):
117    """Like a template syntax error, but covers cases where something in the
118    template caused an error at compile time that wasn't necessarily caused
119    by a syntax error.  However it's a direct subclass of
120    :exc:`TemplateSyntaxError` and has the same attributes.
121    """
122
123
124class TemplateRuntimeError(TemplateError):
125    """A generic runtime error in the template engine.  Under some situations
126    Jinja may raise this exception.
127    """
128
129
130class UndefinedError(TemplateRuntimeError):
131    """Raised if a template tries to operate on :class:`Undefined`."""
132
133
134class SecurityError(TemplateRuntimeError):
135    """Raised if a template tries to do something insecure if the
136    sandbox is enabled.
137    """
138
139
140class FilterArgumentError(TemplateRuntimeError):
141    """This error is raised if a filter was called with inappropriate
142    arguments
143    """
144