Merge pull request #734 from balloob/template-errors

Catch exceptions when errors rendering template
pull/732/head
Paulus Schoutsen 2015-12-12 11:58:38 -08:00
commit ded99d7480
3 changed files with 43 additions and 6 deletions

View File

@ -14,3 +14,10 @@ class InvalidEntityFormatError(HomeAssistantError):
class NoEntitySpecifiedError(HomeAssistantError): class NoEntitySpecifiedError(HomeAssistantError):
""" When no entity is specified. """ """ When no entity is specified. """
pass pass
class TemplateError(HomeAssistantError):
""" Error during template rendering. """
def __init__(self, exception):
super().__init__('{}: {}'.format(exception.__class__.__name__,
exception))

View File

@ -6,10 +6,17 @@ Template utility methods for rendering strings with HA data.
""" """
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
import json import json
import logging
import jinja2
from jinja2.sandbox import ImmutableSandboxedEnvironment from jinja2.sandbox import ImmutableSandboxedEnvironment
from homeassistant.exceptions import TemplateError
_LOGGER = logging.getLogger(__name__)
_SENTINEL = object()
def render_with_possible_json_value(hass, template, value): def render_with_possible_json_value(hass, template, value,
error_value=_SENTINEL):
""" Renders template with value exposed. """ Renders template with value exposed.
If valid JSON will expose value_json too. """ If valid JSON will expose value_json too. """
variables = { variables = {
@ -20,7 +27,11 @@ def render_with_possible_json_value(hass, template, value):
except ValueError: except ValueError:
pass pass
return render(hass, template, variables) try:
return render(hass, template, variables)
except TemplateError:
_LOGGER.exception('Error parsing value')
return value if error_value is _SENTINEL else error_value
def render(hass, template, variables=None, **kwargs): def render(hass, template, variables=None, **kwargs):
@ -28,9 +39,12 @@ def render(hass, template, variables=None, **kwargs):
if variables is not None: if variables is not None:
kwargs.update(variables) kwargs.update(variables)
return ENV.from_string(template, { try:
'states': AllStates(hass) return ENV.from_string(template, {
}).render(kwargs) 'states': AllStates(hass)
}).render(kwargs)
except jinja2.TemplateError as err:
raise TemplateError(err)
class AllStates(object): class AllStates(object):

View File

@ -7,7 +7,7 @@ Tests Home Assistant util methods.
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
import unittest import unittest
import homeassistant.core as ha import homeassistant.core as ha
from homeassistant.exceptions import TemplateError
from homeassistant.util import template from homeassistant.util import template
@ -84,3 +84,19 @@ class TestUtilTemplate(unittest.TestCase):
'', '',
template.render_with_possible_json_value( template.render_with_possible_json_value(
self.hass, '{{ value_json }}', '{ I AM NOT JSON }')) self.hass, '{{ value_json }}', '{ I AM NOT JSON }'))
def test_render_with_possible_json_value_with_template_error(self):
self.assertEqual(
'hello',
template.render_with_possible_json_value(
self.hass, '{{ value_json', 'hello'))
def test_render_with_possible_json_value_with_template_error_error_value(self):
self.assertEqual(
'-',
template.render_with_possible_json_value(
self.hass, '{{ value_json', 'hello', '-'))
def test_raise_exception_on_error(self):
with self.assertRaises(TemplateError):
template.render(self.hass, '{{ invalid_syntax')