Ensure translations for other integrations can be loaded if one integration fails (#110748)

* load failure

* merge
This commit is contained in:
J. Nick Koston 2024-02-17 20:01:36 -06:00 committed by GitHub
parent 0a01161cdd
commit 9bc130c131
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 7 deletions

View File

@ -114,7 +114,7 @@ def _merge_resources(
# We are going to merge the translations for the custom device classes into # We are going to merge the translations for the custom device classes into
# the translations of sensor. # the translations of sensor.
new_value = translation_strings[component].get(category) new_value = translation_strings.get(component, {}).get(category)
if new_value is None: if new_value is None:
continue continue
@ -135,17 +135,17 @@ def _merge_resources(
def build_resources( def build_resources(
translation_strings: dict[str, dict[str, Any]], translation_strings: dict[str, dict[str, dict[str, Any] | str]],
components: set[str], components: set[str],
category: str, category: str,
) -> dict[str, dict[str, Any] | str]: ) -> dict[str, dict[str, Any] | str]:
"""Build the resources response for the given components.""" """Build the resources response for the given components."""
# Build response # Build response
return { return {
component: translation_strings[component][category] component: category_strings
for component in components for component in components
if category in translation_strings[component] if (component_strings := translation_strings.get(component))
and translation_strings[component][category] is not None and (category_strings := component_strings.get(category))
} }
@ -161,7 +161,8 @@ async def _async_get_component_strings(
files_to_load = {} files_to_load = {}
for loaded in components: for loaded in components:
domain = loaded.partition(".")[0] domain = loaded.partition(".")[0]
integration = integrations[domain] if not (integration := integrations.get(domain)):
continue
path = component_translation_path(loaded, language, integration) path = component_translation_path(loaded, language, integration)
# No translation available # No translation available
@ -273,7 +274,10 @@ class _TranslationCache:
ints_or_excs = await async_get_integrations(self.hass, domains) ints_or_excs = await async_get_integrations(self.hass, domains)
for domain, int_or_exc in ints_or_excs.items(): for domain, int_or_exc in ints_or_excs.items():
if isinstance(int_or_exc, Exception): if isinstance(int_or_exc, Exception):
raise int_or_exc _LOGGER.warning(
"Failed to load integration for translation: %s", int_or_exc
)
continue
integrations[domain] = int_or_exc integrations[domain] = int_or_exc
for translation_strings in await asyncio.gather( for translation_strings in await asyncio.gather(

View File

@ -435,6 +435,37 @@ async def test_translation_merging_loaded_together(
assert translations == hue_translations | homekit_translations assert translations == hue_translations | homekit_translations
async def test_ensure_translations_still_load_if_one_integration_fails(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test that if one integration fails to load we can still get translations."""
hass.config.components.add("sensor")
hass.config.components.add("broken")
sensor_integration = await loader.async_get_integration(hass, "sensor")
with patch(
"homeassistant.helpers.translation.async_get_integrations",
return_value={
"sensor": sensor_integration,
"broken": Exception("unhandled failure"),
},
):
translations = await translation.async_get_translations(
hass, "en", "entity_component", integrations={"sensor", "broken"}
)
assert "Failed to load integration for translation" in caplog.text
assert "broken" in caplog.text
assert translations
sensor_translations = await translation.async_get_translations(
hass, "en", "entity_component", integrations={"sensor"}
)
assert translations == sensor_translations
async def test_caching(hass: HomeAssistant) -> None: async def test_caching(hass: HomeAssistant) -> None:
"""Test we cache data.""" """Test we cache data."""
hass.config.components.add("sensor") hass.config.components.add("sensor")