diff --git a/homeassistant/components/google/__init__.py b/homeassistant/components/google/__init__.py index c4e51739efd..bc5e814b24d 100644 --- a/homeassistant/components/google/__init__.py +++ b/homeassistant/components/google/__init__.py @@ -11,7 +11,6 @@ from gcal_sync.api import GoogleCalendarService from gcal_sync.exceptions import ApiException, AuthException from gcal_sync.model import DateOrDatetime, Event import voluptuous as vol -from voluptuous.error import Error as VoluptuousError import yaml from homeassistant.config_entries import ConfigEntry @@ -143,6 +142,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.data.setdefault(DOMAIN, {}) hass.data[DOMAIN][entry.entry_id] = {} + # Validate google_calendars.yaml (if present) as soon as possible to return + # helpful error messages. + try: + await hass.async_add_executor_job(load_config, hass.config.path(YAML_DEVICES)) + except vol.Invalid as err: + _LOGGER.error("Configuration error in %s: %s", YAML_DEVICES, str(err)) + return False + implementation = ( await config_entry_oauth2_flow.async_get_config_entry_implementation( hass, entry @@ -322,11 +329,7 @@ def load_config(path: str) -> dict[str, Any]: with open(path, encoding="utf8") as file: data = yaml.safe_load(file) for calendar in data: - try: - calendars.update({calendar[CONF_CAL_ID]: DEVICE_SCHEMA(calendar)}) - except VoluptuousError as exception: - # keep going - _LOGGER.warning("Calendar Invalid Data: %s", exception) + calendars[calendar[CONF_CAL_ID]] = DEVICE_SCHEMA(calendar) except FileNotFoundError as err: _LOGGER.debug("Error reading calendar configuration: %s", err) # When YAML file could not be loaded/did not contain a dict diff --git a/tests/components/google/test_init.py b/tests/components/google/test_init.py index 4bd09a5f49b..452b2300e5b 100644 --- a/tests/components/google/test_init.py +++ b/tests/components/google/test_init.py @@ -152,11 +152,12 @@ async def test_calendar_yaml_missing_required_fields( component_setup: ComponentSetup, calendars_config: list[dict[str, Any]], mock_calendars_yaml: None, + config_entry: MockConfigEntry, ) -> None: """Test setup with a missing schema fields, ignores the error and continues.""" - assert await component_setup() + assert not await component_setup() - assert not hass.states.get(TEST_YAML_ENTITY) + assert config_entry.state is ConfigEntryState.SETUP_ERROR @pytest.mark.parametrize("calendars_config", [[{"missing-cal_id": "invalid-schema"}]]) @@ -165,23 +166,12 @@ async def test_invalid_calendar_yaml( component_setup: ComponentSetup, calendars_config: list[dict[str, Any]], mock_calendars_yaml: None, - mock_calendars_list: ApiResult, - test_api_calendar: dict[str, Any], - mock_events_list: ApiResult, + config_entry: MockConfigEntry, ) -> None: """Test setup with missing entity id fields fails to load the platform.""" - mock_calendars_list({"items": [test_api_calendar]}) - mock_events_list({}) + assert not await component_setup() - assert await component_setup() - - entries = hass.config_entries.async_entries(DOMAIN) - assert len(entries) == 1 - entry = entries[0] - assert entry.state is ConfigEntryState.LOADED - - assert not hass.states.get(TEST_YAML_ENTITY) - assert not hass.states.get(TEST_API_ENTITY) + assert config_entry.state is ConfigEntryState.SETUP_ERROR async def test_calendar_yaml_error(