From e40908d67cabe9962b7d06cacaed9a6b47b65721 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sat, 7 May 2016 22:24:04 -0700 Subject: [PATCH] Improve config validation error message --- homeassistant/bootstrap.py | 14 ++++++++------ homeassistant/helpers/config_validation.py | 9 +++++++-- homeassistant/util/yaml.py | 8 +++++++- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 6b68f46d4ca..a8e85ca3bd3 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -104,7 +104,7 @@ def _setup_component(hass, domain, config): try: config = component.CONFIG_SCHEMA(config) except vol.MultipleInvalid as ex: - cv.log_exception(_LOGGER, ex, domain) + cv.log_exception(_LOGGER, ex, domain, config) return False elif hasattr(component, 'PLATFORM_SCHEMA'): @@ -114,11 +114,11 @@ def _setup_component(hass, domain, config): try: p_validated = component.PLATFORM_SCHEMA(p_config) except vol.MultipleInvalid as ex: - cv.log_exception(_LOGGER, ex, domain) + cv.log_exception(_LOGGER, ex, domain, p_config) return False # Not all platform components follow same pattern for platforms - # Sof if p_name is None we are not going to validate platform + # So if p_name is None we are not going to validate platform # (the automation component is one of them) if p_name is None: platforms.append(p_validated) @@ -136,7 +136,7 @@ def _setup_component(hass, domain, config): p_validated = platform.PLATFORM_SCHEMA(p_validated) except vol.MultipleInvalid as ex: cv.log_exception(_LOGGER, ex, '{}.{}' - .format(domain, p_name)) + .format(domain, p_name), p_validated) return False platforms.append(p_validated) @@ -228,11 +228,13 @@ def from_config_dict(config, hass=None, config_dir=None, enable_log=True, hass.config.config_dir = config_dir mount_local_lib_path(config_dir) + core_config = config.get(core.DOMAIN, {}) + try: process_ha_core_config(hass, config_util.CORE_CONFIG_SCHEMA( - config.get(core.DOMAIN, {}))) + core_config)) except vol.MultipleInvalid as ex: - cv.log_exception(_LOGGER, ex, 'homeassistant') + cv.log_exception(_LOGGER, ex, 'homeassistant', core_config) return None process_ha_config_upgrade(hass) diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 0bab2674ca6..cea7e95ac5a 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -146,7 +146,7 @@ def time_period_str(value): time_period = vol.Any(time_period_str, timedelta, time_period_dict) -def log_exception(logger, ex, domain): +def log_exception(logger, ex, domain, config): """Generate log exception for config validation.""" message = 'Invalid config for [{}]: '.format(domain) if 'extra keys not allowed' in ex.error_message: @@ -154,7 +154,12 @@ def log_exception(logger, ex, domain): .format(ex.path[-1], domain, domain, '->'.join('%s' % m for m in ex.path)) else: - message += ex.error_message + message += str(ex) + + if hasattr(config, '__line__'): + message += " (See {}:{})".format(config.__config_file__, + config.__line__ or '?') + logger.error(message) diff --git a/homeassistant/util/yaml.py b/homeassistant/util/yaml.py index 8768de5d2f7..bdf0c6d5c41 100644 --- a/homeassistant/util/yaml.py +++ b/homeassistant/util/yaml.py @@ -50,8 +50,11 @@ def _ordered_dict(loader, node): nodes = loader.construct_pairs(node) seen = {} + min_line = None for (key, _), (node, _) in zip(nodes, node.value): line = getattr(node, '__line__', 'unknown') + if line != 'unknown' and (min_line is None or line < min_line): + min_line = line if key in seen: fname = getattr(loader.stream, 'name', '') first_mark = yaml.Mark(fname, 0, seen[key], -1, None, None) @@ -62,7 +65,10 @@ def _ordered_dict(loader, node): ) seen[key] = line - return OrderedDict(nodes) + processed = OrderedDict(nodes) + processed.__config_file__ = loader.name + processed.__line__ = min_line + return processed def _env_var_yaml(loader, node):