mirror of
https://github.com/python-kasa/python-kasa.git
synced 2026-03-10 10:39:57 +00:00
Add ENETUNREACH to non-retryable errors in XorTransport (#1668)
Some checks failed
Stale / stale (push) Has been cancelled
CI / Perform Lint Checks (3.13) (push) Has been cancelled
CodeQL Checks / Analyze (python) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
Some checks failed
Stale / stale (push) Has been cancelled
CI / Perform Lint Checks (3.13) (push) Has been cancelled
CodeQL Checks / Analyze (python) (push) Has been cancelled
CI / Python 3.11 on macos-latest (push) Has been cancelled
CI / Python 3.12 on macos-latest (push) Has been cancelled
CI / Python 3.13 on macos-latest (push) Has been cancelled
CI / Python 3.11 on ubuntu-latest (push) Has been cancelled
CI / Python 3.12 on ubuntu-latest (push) Has been cancelled
CI / Python 3.13 on ubuntu-latest (push) Has been cancelled
CI / Python 3.11 on windows-latest (push) Has been cancelled
CI / Python 3.12 on windows-latest (push) Has been cancelled
CI / Python 3.13 on windows-latest (push) Has been cancelled
`ENETUNREACH` is semantically equivalent to `EHOSTUNREACH` (which is already in `_NO_RETRY_ERRORS`) — both indicate the destination cannot be reached at the network layer. Retrying immediately will not resolve the condition. In containerized environments (e.g., Home Assistant running in Docker with bridge networking), a single ICMP "Network unreachable" response can temporarily poison the container's routing cache. The unnecessary retries reinforce the poisoned cache entry, causing cascading failures for other devices on the same subnet.
This commit is contained in:
@@ -29,7 +29,12 @@ from kasa.json import loads as json_loads
|
|||||||
from .basetransport import BaseTransport
|
from .basetransport import BaseTransport
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
_NO_RETRY_ERRORS = {errno.EHOSTDOWN, errno.EHOSTUNREACH, errno.ECONNREFUSED}
|
_NO_RETRY_ERRORS = {
|
||||||
|
errno.EHOSTDOWN,
|
||||||
|
errno.EHOSTUNREACH,
|
||||||
|
errno.ENETUNREACH,
|
||||||
|
errno.ECONNREFUSED,
|
||||||
|
}
|
||||||
_UNSIGNED_INT_NETWORK_ORDER = struct.Struct(">I")
|
_UNSIGNED_INT_NETWORK_ORDER = struct.Struct(">I")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -807,10 +807,17 @@ async def test_transport_credentials_hash_from_config(mocker, transport_class):
|
|||||||
[
|
[
|
||||||
(ConnectionRefusedError("dummy exception"), False),
|
(ConnectionRefusedError("dummy exception"), False),
|
||||||
(OSError(errno.EHOSTDOWN, os.strerror(errno.EHOSTDOWN)), False),
|
(OSError(errno.EHOSTDOWN, os.strerror(errno.EHOSTDOWN)), False),
|
||||||
|
(OSError(errno.ENETUNREACH, os.strerror(errno.ENETUNREACH)), False),
|
||||||
(OSError(errno.ECONNRESET, os.strerror(errno.ECONNRESET)), True),
|
(OSError(errno.ECONNRESET, os.strerror(errno.ECONNRESET)), True),
|
||||||
(Exception("dummy exception"), True),
|
(Exception("dummy exception"), True),
|
||||||
],
|
],
|
||||||
ids=("ConnectionRefusedError", "OSErrorNoRetry", "OSErrorRetry", "Exception"),
|
ids=(
|
||||||
|
"ConnectionRefusedError",
|
||||||
|
"OSErrorHostDown",
|
||||||
|
"OSErrorNetUnreach",
|
||||||
|
"OSErrorRetry",
|
||||||
|
"Exception",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("protocol_class", "transport_class"),
|
("protocol_class", "transport_class"),
|
||||||
|
|||||||
Reference in New Issue
Block a user