Skip to content

Commit 09a4469

Browse files
committed
Introduce Update logic specific exceptions
Add Update specific exceptions and raise them where appropriate.
1 parent 93f3894 commit 09a4469

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

matter_server/common/errors.py

+12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ class InvalidCommand(MatterError):
7777
error_code = 9
7878

7979

80+
class UpdateCheckError(MatterError):
81+
"""Error raised when there was an error during searching for updates."""
82+
83+
error_code = 10
84+
85+
86+
class UpdateError(MatterError):
87+
"""Error raised when there was an error during applying updates."""
88+
89+
error_code = 11
90+
91+
8092
def exception_from_error_code(error_code: int) -> type[MatterError]:
8193
"""Return correct Exception class from error_code."""
8294
return ERROR_MAP.get(error_code, MatterError)

matter_server/server/device_controller.py

+26-22
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
NodeNotExists,
4444
NodeNotReady,
4545
NodeNotResolving,
46+
UpdateCheckError,
47+
UpdateError,
4648
)
4749
from ..common.helpers.api import api_command
4850
from ..common.helpers.json import JSON_DECODE_EXCEPTIONS, json_loads
@@ -921,19 +923,15 @@ async def update_node(self, node_id: int, software_version: int) -> dict | None:
921923

922924
update = await self._check_node_update(node_id, software_version)
923925
if update is None:
924-
logging.error(
925-
"Software version %d is not available for node %d",
926-
software_version,
927-
node_id,
926+
raise UpdateCheckError(
927+
f"Software version {software_version} is not available for node {node_id}."
928928
)
929-
return None
930929

931930
if self.chip_controller is None:
932931
raise RuntimeError("Device Controller not initialized.")
933932

934933
if not self._ota_provider:
935-
LOGGER.warning("No OTA provider found, updates not possible.")
936-
return None
934+
raise UpdateError("No OTA provider found, updates not possible.")
937935

938936
# Add update to the OTA provider
939937
await self._ota_provider.download_update(update)
@@ -1011,26 +1009,33 @@ async def update_node(self, node_id: int, software_version: int) -> dict | None:
10111009
)
10121010
)
10131011
if write_result[0].Status != Status.Success:
1014-
logging.error("Failed writing adjusted OTA Provider App ACL.")
1012+
logging.error(
1013+
"Failed writing adjusted OTA Provider App ACL: Status %s.",
1014+
str(write_result[0].Status),
1015+
)
10151016
await self.remove_node(ota_provider_node_id)
1016-
return None
1017+
raise UpdateError("Error while setting up OTA Provider.")
10171018
except ChipStackError as ex:
10181019
logging.exception("Failed adjusting OTA Provider App ACL.", exc_info=ex)
10191020
await self.remove_node(ota_provider_node_id)
1020-
else:
1021-
self._ota_provider.set_node_id(ota_provider_node_id)
1021+
raise UpdateError("Error while setting up OTA Provider.") from ex
1022+
1023+
self._ota_provider.set_node_id(ota_provider_node_id)
10221024

10231025
# Notify node about the new update!
1024-
await self.chip_controller.SendCommand(
1025-
nodeid=node_id,
1026-
endpoint=0,
1027-
payload=Clusters.OtaSoftwareUpdateRequestor.Commands.AnnounceOTAProvider(
1028-
providerNodeID=ota_provider_node_id,
1029-
vendorID=0, # TODO: Use Server Vendor ID
1030-
announcementReason=Clusters.OtaSoftwareUpdateRequestor.Enums.AnnouncementReasonEnum.kUpdateAvailable,
1026+
try:
1027+
await self.chip_controller.SendCommand(
1028+
nodeid=node_id,
10311029
endpoint=0,
1032-
),
1033-
)
1030+
payload=Clusters.OtaSoftwareUpdateRequestor.Commands.AnnounceOTAProvider(
1031+
providerNodeID=ota_provider_node_id,
1032+
vendorID=self.server.vendor_id,
1033+
announcementReason=Clusters.OtaSoftwareUpdateRequestor.Enums.AnnouncementReasonEnum.kUpdateAvailable,
1034+
endpoint=ExternalOtaProvider.ENDPOINT_ID,
1035+
),
1036+
)
1037+
except ChipStackError as ex:
1038+
raise UpdateError("Error while announcing OTA Provider to node.") from ex
10341039

10351040
return update
10361041

@@ -1062,8 +1067,7 @@ async def _check_node_update(
10621067
return None
10631068

10641069
if "otaUrl" not in update:
1065-
node_logger.warning("Update found, but no OTA URL provided.")
1066-
return None
1070+
raise UpdateCheckError("Update found, but no OTA URL provided.")
10671071

10681072
node_logger.info(
10691073
"New software update found: %s (current %s).",

matter_server/server/ota/dcl.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from aiohttp import ClientError, ClientSession
77

8+
from matter_server.common.errors import UpdateCheckError
89
from matter_server.server.helpers import DCL_PRODUCTION_URL
910

1011
LOGGER = logging.getLogger(__name__)
@@ -92,5 +93,4 @@ async def check_for_update(
9293
return None
9394

9495
except (ClientError, TimeoutError) as err:
95-
LOGGER.error("Fetching software version failed: error %s", err, exc_info=err)
96-
return None
96+
raise UpdateCheckError("Fetching software version failed.") from err

matter_server/server/ota/provider.py

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ class ExternalOtaProvider:
5454
for devices.
5555
"""
5656

57+
ENDPOINT_ID: Final[int] = 0
58+
5759
def __init__(self, ota_provider_dir: Path) -> None:
5860
"""Initialize the OTA provider."""
5961
self._ota_provider_dir: Path = ota_provider_dir

0 commit comments

Comments
 (0)