From c9d1b127d81971ae34f0ffcc3acee17a80196458 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 20 May 2024 17:26:48 -1000 Subject: [PATCH] Improve error message when template is rendered from wrong thread (#117822) * Improve error message when template is rendered from wrong thread * Improve error message when template is rendered from wrong thread --- homeassistant/helpers/template.py | 11 ++++++++++- tests/helpers/test_template.py | 27 +++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 32c0ff244a6..d67e9b406c4 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -688,10 +688,19 @@ class Template: if self.hass and self.hass.config.debug: self.hass.verify_event_loop_thread("async_render_to_info") self._renders += 1 - assert self.hass and _render_info.get() is None render_info = RenderInfo(self) + if not self.hass: + raise RuntimeError(f"hass not set while rendering {self}") + + if _render_info.get() is not None: + raise RuntimeError( + f"RenderInfo already set while rendering {self}, " + "this usually indicates the template is being rendered " + "in the wrong thread" + ) + if self.is_static: render_info._result = self.template.strip() # noqa: SLF001 render_info._freeze_static() # noqa: SLF001 diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 2561396d387..71e1bc748a6 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -119,6 +119,33 @@ def assert_result_info( assert not hasattr(info, "_domains") +async def test_template_render_missing_hass(hass: HomeAssistant) -> None: + """Test template render when hass is not set.""" + hass.states.async_set("sensor.test", "23") + template_str = "{{ states('sensor.test') }}" + template_obj = template.Template(template_str, None) + template._render_info.set(template.RenderInfo(template_obj)) + + with pytest.raises(RuntimeError, match="hass not set while rendering"): + template_obj.async_render_to_info() + + +async def test_template_render_info_collision(hass: HomeAssistant) -> None: + """Test template render info collision. + + This usually means the template is being rendered + in the wrong thread. + """ + hass.states.async_set("sensor.test", "23") + template_str = "{{ states('sensor.test') }}" + template_obj = template.Template(template_str, None) + template_obj.hass = hass + template._render_info.set(template.RenderInfo(template_obj)) + + with pytest.raises(RuntimeError, match="RenderInfo already set while rendering"): + template_obj.async_render_to_info() + + def test_template_equality() -> None: """Test template comparison and hashing.""" template_one = template.Template("{{ template_one }}")