Merge branch 'improve/templateErrorResilience' into devel

Conflicts:
	src/octoprint/server/__init__.py
This commit is contained in:
Gina Häußge 2016-07-06 15:10:48 +02:00
commit 0015d844a8
6 changed files with 58 additions and 89 deletions

View file

@ -633,37 +633,6 @@ class Server(object):
app.jinja_env.add_extension("jinja2.ext.do")
app.jinja_env.add_extension("octoprint.util.jinja.trycatch")
def regex_replace(s, find, replace):
return re.sub(find, replace, s)
html_header_regex = re.compile("<h(?P<number>[1-6])>(?P<content>.*?)</h(?P=number)>")
def offset_html_headers(s, offset):
def repl(match):
number = int(match.group("number"))
number += offset
if number > 6:
number = 6
elif number < 1:
number = 1
return "<h{number}>{content}</h{number}>".format(number=number, content=match.group("content"))
return html_header_regex.sub(repl, s)
markdown_header_regex = re.compile("^(?P<hashs>#+)\s+(?P<content>.*)$", flags=re.MULTILINE)
def offset_markdown_headers(s, offset):
def repl(match):
number = len(match.group("hashs"))
number += offset
if number > 6:
number = 6
elif number < 1:
number = 1
return "{hashs} {content}".format(hashs="#" * number, content=match.group("content"))
return markdown_header_regex.sub(repl, s)
app.jinja_env.filters["regex_replace"] = regex_replace
app.jinja_env.filters["offset_html_headers"] = offset_html_headers
app.jinja_env.filters["offset_markdown_headers"] = offset_markdown_headers
def regex_replace(s, find, replace):
return re.sub(find, replace, s)

View file

@ -38,7 +38,7 @@
class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}"
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %}
>
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</div>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endif %}

View file

@ -38,7 +38,7 @@
class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}"
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %}
>
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</div>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endif %}

View file

@ -35,7 +35,7 @@
class="tab-pane {% if mark_active %}active{% set mark_active = False %}{% endif %} {% if classes_content in data %}{{ data.classes_content|join(' ') }}{% elif classes in data %}{{ data.classes|join(' ') }}{% endif %}"
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif styles in data %} style="{{ data.styles|join(', ') }}" {% endif %}
>
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</div>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endif %}

View file

@ -31,7 +31,7 @@
{% if "classes" in data %}class="{{ data.classes|join(' ') }}"{% endif %}
{% if "styles" in data %}style="{{ data.styles|join(', ') }}"{% endif %}
>
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</li>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endfor %}
@ -58,7 +58,7 @@
{% if "icon" in data %}<i class="icon-{{ data.icon }}"></i> {% endif %}{{ entry|e }}
</a>
{% if "template_header" in data %}
{% include data.template_header ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template_header ignore missing %}{% endtry %}
{% endif %}
</div>
<div id="{{ data._div }}"
@ -66,7 +66,7 @@
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}"{% endif %}
>
<div class="accordion-inner">
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</div>
</div>
</div>
@ -102,7 +102,7 @@
{% if "data_bind" in data %}data-bind="{{ data.data_bind }}"{% endif %}
{% if "styles_content" in data %} style="{{ data.styles_content|join(', ') }}" {% elif "styles" in data %} style="{{ data.styles|join(', ') }}" {% endif %}
>
{% include data.template ignore missing %}
{% try "There was an error with the template {filename} at line number {lineno}: {exception}" %}{% include data.template ignore missing %}{% endtry %}
</div>
{% if "custom_bindings" not in data or data["custom_bindings"] %}<!-- /ko -->{% endif %}
{% endfor %}
@ -142,7 +142,7 @@
<!-- Generic plugin template files -->
{% for key in templates.generic.order %}
{% set data = templates.generic.entries[key] %}
{% include data.template ignore missing %}
{% try "<!-- There was an error with the template {filename} at line number {lineno}: {exception} -->" %}{% include data.template ignore missing %}{% endtry %}
{% endfor %}
<!-- End of generic plugin template files -->

View file

@ -87,56 +87,6 @@ class SelectedFilesLoader(BaseLoader):
return self.files.keys()
class ExceptionHandlerExtension(Extension):
tags = {"try"}
def __init__(self, environment):
super(ExceptionHandlerExtension, self).__init__(environment)
self._logger = logging.getLogger(__name__)
def parse(self, parser):
token = parser.stream.next()
lineno = token.lineno
filename = parser.name
error = parser.parse_expression()
args = [error, nodes.Const(filename), nodes.Const(lineno)]
try:
body = parser.parse_statements(["name:endtry"], drop_needle=True)
node = nodes.CallBlock(self.call_method("_handle_body", args),
[], [], body).set_lineno(lineno)
except Exception as e:
# that was expected
self._logger.exception("Caught exception while parsing template")
node = nodes.CallBlock(self.call_method("_handle_error", [nodes.Const(self._format_error(error, e, filename, lineno))]),
[], [], []).set_lineno(lineno)
return node
def _handle_body(self, error, filename, lineno, caller):
try:
return caller()
except Exception as e:
self._logger.exception("Caught exception while compiling template {filename} at line {lineno}".format(**locals()))
error_string = self._format_error(error, e, filename, lineno)
return error_string if error_string else ""
def _handle_error(self, error, caller):
return error if error else ""
def _format_error(self, error, exception, filename, lineno):
if not error:
return ""
try:
return error.format(exception=exception, filename=filename, lineno=lineno)
except:
self._logger.exception("Error while compiling exception output for template {filename} at line {lineno}".format(**locals()))
return "Unknown error"
trycatch = ExceptionHandlerExtension
def get_all_template_paths(loader):
def walk_folder(folder):
files = []
@ -196,3 +146,53 @@ def get_all_asset_paths(env):
# intentionally ignored
pass
return result
class ExceptionHandlerExtension(Extension):
tags = {"try"}
def __init__(self, environment):
super(ExceptionHandlerExtension, self).__init__(environment)
self._logger = logging.getLogger(__name__)
def parse(self, parser):
token = parser.stream.next()
lineno = token.lineno
filename = parser.name
error = parser.parse_expression()
args = [error, nodes.Const(filename), nodes.Const(lineno)]
try:
body = parser.parse_statements(["name:endtry"], drop_needle=True)
node = nodes.CallBlock(self.call_method("_handle_body", args),
[], [], body).set_lineno(lineno)
except Exception as e:
# that was expected
self._logger.exception("Caught exception while parsing template")
node = nodes.CallBlock(self.call_method("_handle_error", [nodes.Const(self._format_error(error, e, filename, lineno))]),
[], [], []).set_lineno(lineno)
return node
def _handle_body(self, error, filename, lineno, caller):
try:
return caller()
except Exception as e:
self._logger.exception("Caught exception while compiling template {filename} at line {lineno}".format(**locals()))
error_string = self._format_error(error, e, filename, lineno)
return error_string if error_string else ""
def _handle_error(self, error, caller):
return error if error else ""
def _format_error(self, error, exception, filename, lineno):
if not error:
return ""
try:
return error.format(exception=exception, filename=filename, lineno=lineno)
except:
self._logger.exception("Error while compiling exception output for template {filename} at line {lineno}".format(**locals()))
return "Unknown error"
trycatch = ExceptionHandlerExtension