mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Fix error handling in Shell Command integration (#116409)
* raise proper HomeAssistantError on command timeout * raise proper HomeAssistantError on non-utf8 command output * add error translation and test it * Update homeassistant/components/shell_command/strings.json * Update tests/components/shell_command/test_init.py --------- Co-authored-by: G Johansson <goran.johansson@shiftit.se>
This commit is contained in:
parent
d1c58467c5
commit
50d83bbdbf
@ -15,7 +15,7 @@ from homeassistant.core import (
|
||||
ServiceResponse,
|
||||
SupportsResponse,
|
||||
)
|
||||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.exceptions import HomeAssistantError, TemplateError
|
||||
from homeassistant.helpers import config_validation as cv, template
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.util.json import JsonObjectType
|
||||
@ -91,7 +91,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
try:
|
||||
async with asyncio.timeout(COMMAND_TIMEOUT):
|
||||
stdout_data, stderr_data = await process.communicate()
|
||||
except TimeoutError:
|
||||
except TimeoutError as err:
|
||||
_LOGGER.error(
|
||||
"Timed out running command: `%s`, after: %ss", cmd, COMMAND_TIMEOUT
|
||||
)
|
||||
@ -103,7 +103,14 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
process._transport.close() # type: ignore[attr-defined]
|
||||
del process
|
||||
|
||||
raise
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="timeout",
|
||||
translation_placeholders={
|
||||
"command": cmd,
|
||||
"timeout": str(COMMAND_TIMEOUT),
|
||||
},
|
||||
) from err
|
||||
|
||||
if stdout_data:
|
||||
_LOGGER.debug(
|
||||
@ -135,11 +142,15 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
service_response["stdout"] = stdout_data.decode("utf-8").strip()
|
||||
if stderr_data:
|
||||
service_response["stderr"] = stderr_data.decode("utf-8").strip()
|
||||
except UnicodeDecodeError:
|
||||
except UnicodeDecodeError as err:
|
||||
_LOGGER.exception(
|
||||
"Unable to handle non-utf8 output of command: `%s`", cmd
|
||||
)
|
||||
raise
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="non_utf8_output",
|
||||
translation_placeholders={"command": cmd},
|
||||
) from err
|
||||
return service_response
|
||||
return None
|
||||
|
||||
|
10
homeassistant/components/shell_command/strings.json
Normal file
10
homeassistant/components/shell_command/strings.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"exceptions": {
|
||||
"timeout": {
|
||||
"message": "Timed out running command: `{command}`, after: {timeout} seconds"
|
||||
},
|
||||
"non_utf8_output": {
|
||||
"message": "Unable to handle non-utf8 output of command: `{command}`"
|
||||
}
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import pytest
|
||||
|
||||
from homeassistant.components import shell_command
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.exceptions import HomeAssistantError, TemplateError
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
||||
@ -199,7 +199,10 @@ async def test_non_text_stdout_capture(
|
||||
assert not response
|
||||
|
||||
# Non-text output throws with 'return_response'
|
||||
with pytest.raises(UnicodeDecodeError):
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Unable to handle non-utf8 output of command: `curl -o - https://raw.githubusercontent.com/home-assistant/assets/master/misc/loading-screen.gif`",
|
||||
):
|
||||
response = await hass.services.async_call(
|
||||
"shell_command", "output_image", blocking=True, return_response=True
|
||||
)
|
||||
@ -258,7 +261,10 @@ async def test_do_not_run_forever(
|
||||
side_effect=mock_create_subprocess_shell,
|
||||
),
|
||||
):
|
||||
with pytest.raises(TimeoutError):
|
||||
with pytest.raises(
|
||||
HomeAssistantError,
|
||||
match="Timed out running command: `mock_sleep 10000`, after: 0.001 seconds",
|
||||
):
|
||||
await hass.services.async_call(
|
||||
shell_command.DOMAIN,
|
||||
"test_service",
|
||||
|
Loading…
x
Reference in New Issue
Block a user