Raise ConditionError for and/or/not errors (#46767)

This commit is contained in:
Anders Melchiorsen 2021-02-19 13:15:30 +01:00 committed by GitHub
parent e7e3e09063
commit bfea7d0baa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 22 deletions

View file

@ -615,12 +615,21 @@ async def _async_process_if(hass, config, p_config):
def if_action(variables=None): def if_action(variables=None):
"""AND all conditions.""" """AND all conditions."""
try: errors = []
return all(check(hass, variables) for check in checks) for check in checks:
except ConditionError as ex: try:
LOGGER.warning("Error in 'condition' evaluation: %s", ex) if not check(hass, variables):
return False
except ConditionError as ex:
errors.append(f"Error in 'condition' evaluation: {ex}")
if errors:
for error in errors:
LOGGER.warning("%s", error)
return False return False
return True
if_action.config = if_configs if_action.config = if_configs
return if_action return if_action

View file

@ -108,13 +108,19 @@ async def async_and_from_config(
hass: HomeAssistant, variables: TemplateVarsType = None hass: HomeAssistant, variables: TemplateVarsType = None
) -> bool: ) -> bool:
"""Test and condition.""" """Test and condition."""
try: errors = []
for check in checks: for check in checks:
try:
if not check(hass, variables): if not check(hass, variables):
return False return False
except Exception as ex: # pylint: disable=broad-except except ConditionError as ex:
_LOGGER.warning("Error during and-condition: %s", ex) errors.append(str(ex))
return False except Exception as ex: # pylint: disable=broad-except
errors.append(str(ex))
# Raise the errors if no check was false
if errors:
raise ConditionError("Error in 'and' condition: " + ", ".join(errors))
return True return True
@ -134,13 +140,20 @@ async def async_or_from_config(
def if_or_condition( def if_or_condition(
hass: HomeAssistant, variables: TemplateVarsType = None hass: HomeAssistant, variables: TemplateVarsType = None
) -> bool: ) -> bool:
"""Test and condition.""" """Test or condition."""
try: errors = []
for check in checks: for check in checks:
try:
if check(hass, variables): if check(hass, variables):
return True return True
except Exception as ex: # pylint: disable=broad-except except ConditionError as ex:
_LOGGER.warning("Error during or-condition: %s", ex) errors.append(str(ex))
except Exception as ex: # pylint: disable=broad-except
errors.append(str(ex))
# Raise the errors if no check was true
if errors:
raise ConditionError("Error in 'or' condition: " + ", ".join(errors))
return False return False
@ -161,12 +174,19 @@ async def async_not_from_config(
hass: HomeAssistant, variables: TemplateVarsType = None hass: HomeAssistant, variables: TemplateVarsType = None
) -> bool: ) -> bool:
"""Test not condition.""" """Test not condition."""
try: errors = []
for check in checks: for check in checks:
try:
if check(hass, variables): if check(hass, variables):
return False return False
except Exception as ex: # pylint: disable=broad-except except ConditionError as ex:
_LOGGER.warning("Error during not-condition: %s", ex) errors.append(str(ex))
except Exception as ex: # pylint: disable=broad-except
errors.append(str(ex))
# Raise the errors if no check was true
if errors:
raise ConditionError("Error in 'not' condition: " + ", ".join(errors))
return True return True

View file

@ -50,6 +50,9 @@ async def test_and_condition(hass):
}, },
) )
with pytest.raises(ConditionError):
test(hass)
hass.states.async_set("sensor.temperature", 120) hass.states.async_set("sensor.temperature", 120)
assert not test(hass) assert not test(hass)
@ -111,6 +114,9 @@ async def test_or_condition(hass):
}, },
) )
with pytest.raises(ConditionError):
test(hass)
hass.states.async_set("sensor.temperature", 120) hass.states.async_set("sensor.temperature", 120)
assert not test(hass) assert not test(hass)
@ -169,6 +175,9 @@ async def test_not_condition(hass):
}, },
) )
with pytest.raises(ConditionError):
test(hass)
hass.states.async_set("sensor.temperature", 101) hass.states.async_set("sensor.temperature", 101)
assert test(hass) assert test(hass)
@ -466,7 +475,8 @@ async def test_state_attribute(hass):
) )
hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 200}) hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 200})
assert not test(hass) with pytest.raises(ConditionError):
test(hass)
hass.states.async_set("sensor.temperature", 100, {"attribute1": 200}) hass.states.async_set("sensor.temperature", 100, {"attribute1": 200})
assert test(hass) assert test(hass)
@ -720,7 +730,7 @@ async def test_numeric_state_multiple_entities(hass):
assert not test(hass) assert not test(hass)
async def test_numberic_state_attribute(hass): async def test_numeric_state_attribute(hass):
"""Test with numeric state attribute in condition.""" """Test with numeric state attribute in condition."""
test = await condition.async_from_config( test = await condition.async_from_config(
hass, hass,
@ -738,7 +748,8 @@ async def test_numberic_state_attribute(hass):
) )
hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 10}) hass.states.async_set("sensor.temperature", 100, {"unkown_attr": 10})
assert not test(hass) with pytest.raises(ConditionError):
assert test(hass)
hass.states.async_set("sensor.temperature", 100, {"attribute1": 49}) hass.states.async_set("sensor.temperature", 100, {"attribute1": 49})
assert test(hass) assert test(hass)
@ -750,7 +761,8 @@ async def test_numberic_state_attribute(hass):
assert not test(hass) assert not test(hass)
hass.states.async_set("sensor.temperature", 100, {"attribute1": None}) hass.states.async_set("sensor.temperature", 100, {"attribute1": None})
assert not test(hass) with pytest.raises(ConditionError):
assert test(hass)
async def test_numeric_state_using_input_number(hass): async def test_numeric_state_using_input_number(hass):