Merge branch 'improve/templateErrorResilience' into devel
Conflicts: src/octoprint/server/__init__.py
This commit is contained in:
commit
0015d844a8
6 changed files with 58 additions and 89 deletions
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 -->
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue