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