Skip to content

Commit 8c22aa5

Browse files
committed
Raise InvalidServerVersion when Server is too old too
Currently InvalidServerVersion was only raised when the client was too old (Server wasn't able to handle such an old client anymore), e.g. after a backwards incompatible change Server side. However, if the client was newer than the Server schema version, no error was raised. This essentially never triggered the add-on update logic in Core. This change makes sure that we raise InvalidServerVersion when the Server is too old for the client too. We also add properties to the Exception so a client can figure out which situation we are dealing with (too old/too new) and act accordingly.
1 parent 0764463 commit 8c22aa5

File tree

3 files changed

+40
-23
lines changed

3 files changed

+40
-23
lines changed

matter_server/client/client.py

+22-21
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from chip.clusters import Objects as Clusters
1111
from chip.clusters.Types import NullValue
1212

13+
from matter_server.common.const import SCHEMA_VERSION
1314
from matter_server.common.errors import ERROR_MAP, NodeNotExists
1415

1516
from ..common.helpers.util import (
@@ -535,14 +536,13 @@ async def update_node(
535536
APICommand.UPDATE_NODE, node_id=node_id, software_version=software_version
536537
)
537538

538-
async def send_command(
539+
def _prepare_message(
539540
self,
540541
command: str,
541542
require_schema: int | None = None,
542543
**kwargs: Any,
543-
) -> Any:
544-
"""Send a command and get a response."""
545-
if not self.connection.connected or not self._loop:
544+
) -> CommandMessage:
545+
if not self.connection.connected:
546546
raise InvalidState("Not connected")
547547

548548
if (
@@ -552,14 +552,29 @@ async def send_command(
552552
):
553553
raise InvalidServerVersion(
554554
"Command not available due to incompatible server version. Update the Matter "
555-
f"Server to a version that supports at least api schema {require_schema}."
555+
f"Server to a version that supports at least api schema {require_schema}.",
556+
SCHEMA_VERSION,
557+
self.server_info.schema_version,
558+
self.server_info.min_supported_schema_version,
556559
)
557560

558-
message = CommandMessage(
561+
return CommandMessage(
559562
message_id=uuid.uuid4().hex,
560563
command=command,
561564
args=kwargs,
562565
)
566+
567+
async def send_command(
568+
self,
569+
command: str,
570+
require_schema: int | None = None,
571+
**kwargs: Any,
572+
) -> Any:
573+
"""Send a command and get a response."""
574+
if not self._loop:
575+
raise InvalidState("Not connected")
576+
577+
message = self._prepare_message(command, require_schema, **kwargs)
563578
future: asyncio.Future[Any] = self._loop.create_future()
564579
self._result_futures[message.message_id] = future
565580
await self.connection.send_message(message)
@@ -575,22 +590,8 @@ async def send_command_no_wait(
575590
**kwargs: Any,
576591
) -> None:
577592
"""Send a command without waiting for the response."""
578-
if not self.server_info:
579-
raise InvalidState("Not connected")
580593

581-
if (
582-
require_schema is not None
583-
and require_schema > self.server_info.schema_version
584-
):
585-
raise InvalidServerVersion(
586-
"Command not available due to incompatible server version. Update the Matter "
587-
f"Server to a version that supports at least api schema {require_schema}."
588-
)
589-
message = CommandMessage(
590-
message_id=uuid.uuid4().hex,
591-
command=command,
592-
args=kwargs,
593-
)
594+
message = self._prepare_message(command, require_schema, **kwargs)
594595
await self.connection.send_message(message)
595596

596597
async def get_diagnostics(self) -> ServerDiagnostics:

matter_server/client/connection.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,16 @@ async def connect(self) -> None:
8080
self.server_info = info
8181

8282
# basic check for server schema version compatibility
83-
if info.min_supported_schema_version > SCHEMA_VERSION:
83+
if info.min_supported_schema_version > SCHEMA_VERSION > info.schema_version:
8484
# our schema version is too low and can't be handled by the server anymore.
8585
await self._ws_client.close()
8686
raise InvalidServerVersion(
8787
f"Matter schema version is incompatible: {SCHEMA_VERSION}, "
8888
f"the server requires at least {info.min_supported_schema_version} "
89-
" - update the Matter client to a more recent version or downgrade the server."
89+
" - update the Matter client to a more recent version or downgrade the server.",
90+
SCHEMA_VERSION,
91+
info.schema_version,
92+
info.min_supported_schema_version,
9093
)
9194

9295
LOGGER.info(

matter_server/client/exceptions.py

+13
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,16 @@ class InvalidMessage(MatterClientException):
5353

5454
class InvalidServerVersion(MatterClientException):
5555
"""Exception raised when connected to server with incompatible version."""
56+
57+
def __init__(
58+
self,
59+
msg: str,
60+
client_schema_version: int,
61+
server_schema_version: int,
62+
min_supported_schema_version: int,
63+
):
64+
"""Initialize an invalid server version error."""
65+
super().__init__(msg)
66+
self.client_schema_version = client_schema_version
67+
self.server_schema_version = server_schema_version
68+
self.min_supported_schema_version = min_supported_schema_version

0 commit comments

Comments
 (0)