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):
"""AND all conditions."""
try:
return all(check(hass, variables) for check in checks)
except ConditionError as ex:
LOGGER.warning("Error in 'condition' evaluation: %s", ex)
errors = []
for check in checks:
try:
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 True
if_action.config = if_configs
return if_action

View file

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

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)
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)
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)
assert test(hass)
@ -466,7 +475,8 @@ async def test_state_attribute(hass):
)
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})
assert test(hass)
@ -720,7 +730,7 @@ async def test_numeric_state_multiple_entities(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 = await condition.async_from_config(
hass,
@ -738,7 +748,8 @@ async def test_numberic_state_attribute(hass):
)
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})
assert test(hass)
@ -750,7 +761,8 @@ async def test_numberic_state_attribute(hass):
assert not test(hass)
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):