exceptions.py 5.3 KB

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