Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Consider handshake as still valid on ServerDisconnectedError #676

Copy link
Copy link
@bdraco

Description

@bdraco
Issue body actions

ServerDisconnectedError seems to be normal behavior for the device and the next query is successful. We shouldn't redo the handshake in this case

diff --git a/kasa/httpclient.py b/kasa/httpclient.py
index a4bd84a..c03cd78 100644
--- a/kasa/httpclient.py
+++ b/kasa/httpclient.py
@@ -64,8 +64,13 @@ class HttpClient:
                     response_data = await resp.read()
                     if json:
                         response_data = json_loads(response_data.decode())
-
-        except (aiohttp.ServerDisconnectedError, aiohttp.ClientOSError) as ex:
+        except aiohttp.ServerDisconnectedError as ex:
+            # Server disconnected error is raised when the device closes the connection
+            # before the request is completed. This is normal behavior for the device.
+            raise DisconnectedException(
+                f"Device disconnected: {self._config.host}: {ex}", ex
+            ) from ex
+        except aiohttp.ClientOSError as ex:
             raise ConnectionException(
                 f"Unable to connect to the device: {self._config.host}: {ex}", ex
             ) from ex
diff --git a/kasa/smartprotocol.py b/kasa/smartprotocol.py
index c28db94..b7464f9 100644
--- a/kasa/smartprotocol.py
+++ b/kasa/smartprotocol.py
@@ -65,6 +65,14 @@ class SmartProtocol(BaseProtocol):
         for retry in range(retry_count + 1):
             try:
                 return await self._execute_query(request, retry)
+            except DisconnectedException as dex:
+                # Do not call close() here as the connection is already closed
+                # this is is a normal behavior for the device. Its likely that
+                # the credentials are not expired and the next query will succeed.
+                if retry >= retry_count:
+                    _LOGGER.debug("Giving up on %s after %s retries", self._host, retry)
+                    raise dex
+                continue
             except ConnectionException as sdex:
                 await self.close()
                 if retry >= retry_count:
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.