Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import logging
import socket
import sys
from errno import ENETUNREACH, EHOSTUNREACH
from pathlib import Path
from typing import Any

Expand Down Expand Up @@ -162,7 +163,7 @@ async def async_execute(self, data: dict[str, Any]) -> dict[str, Any]:
translation_key="connection_timed_out",
) from exc
except OSError as exc:
if isinstance(exc, socket.gaierror):
if isinstance(exc, socket.gaierror) or exc.errno in (ENETUNREACH, EHOSTUNREACH):
_LOGGER.warning("Host %s is not reachable: %s", host, exc)
raise ServiceValidationError(
"Host is not reachable.",
Expand Down
21 changes: 21 additions & 0 deletions tests/integration_tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,27 @@ async def test_host_not_reachable(self, hass: HomeAssistant) -> None:

assert exc_info.value.translation_key == "host_not_reachable"

async def test_network_unreachable(self, hass: HomeAssistant) -> None:
from errno import ENETUNREACH

err = OSError(ENETUNREACH, "Connect call failed ('192.0.2.1', 22)")
entry = _make_entry()
await _setup_entry(hass, entry)

with patch("custom_components.ssh_command.coordinator.connect",
return_value=_MockConnectRaises(err)):
with patch("pathlib.Path.exists", return_value=False):
with pytest.raises(ServiceValidationError) as exc_info:
await hass.services.async_call(
DOMAIN,
SERVICE_EXECUTE,
SERVICE_DATA_BASE,
blocking=True,
return_response=True,
)

assert exc_info.value.translation_key == "host_not_reachable"

async def test_other_oserror_is_reraised(self, hass: HomeAssistant) -> None:
err = OSError("something else")
entry = _make_entry()
Expand Down
10 changes: 10 additions & 0 deletions tests/unit_tests/test_coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,16 @@ async def test_async_execute_name_resolution_failure(self):

self.assertEqual(ctx.exception.translation_key, "host_not_reachable")

async def test_async_execute_network_unreachable(self):
from errno import ENETUNREACH

Comment thread
Copilot marked this conversation as resolved.
err = OSError(ENETUNREACH, "Connect call failed ('192.0.2.1', 22)")
with patch("ssh_command.coordinator.connect", return_value=_MockConnectRaises(err)):
with self.assertRaises(ServiceValidationError) as ctx:
await self.coordinator.async_execute(EXECUTE_DATA_BASE)

self.assertEqual(ctx.exception.translation_key, "host_not_reachable")

async def test_async_execute_other_oserror_reraised(self):
err = OSError("something else")

Expand Down
Loading