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
43 changes: 43 additions & 0 deletions tests/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,49 @@ async def endpoint_reply(cluster, sequence, data, **kwargs):
await zha_gateway.async_block_till_done()


async def test_firmware_update_empty_exception_message(zha_gateway: Gateway) -> None:
"""Bare ``TimeoutError()`` from zigpy must still produce an identifiable message."""
zigpy_device = zigpy_device_mock(zha_gateway)
zha_device, ota_cluster, fw_image, installed_fw_version = await setup_test_data(
zha_gateway, zigpy_device
)

entity = get_entity(zha_device, platform=Platform.UPDATE)

await ota_cluster._handle_query_next_image(
foundation.ZCLHeader.cluster(
tsn=0x12, command_id=general.Ota.ServerCommandDefs.query_next_image.id
),
general.QueryNextImageCommand(
field_control=fw_image.firmware.header.field_control,
manufacturer_code=zha_device.manufacturer_code,
image_type=fw_image.firmware.header.image_type,
current_file_version=installed_fw_version,
hardware_version=1,
),
)
await zha_gateway.async_block_till_done()

raised = TimeoutError()
assert str(raised) == ""

with (
patch(
"zigpy.device.Device.update_firmware",
AsyncMock(side_effect=raised),
),
pytest.raises(ZHAException) as exc_info,
):
await entity.async_install(
version=f"0x{fw_image.firmware.header.file_version:08x}"
)
Comment on lines +535 to +544
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern is copied from the existing tests. This is technically somewhat correct, but we generally don't guard for failure cases in tests like this. I'd just leave this as is.

await zha_gateway.async_block_till_done()

assert str(exc_info.value) == "Update was not successful: TimeoutError()"
assert exc_info.value.__cause__ is raised
assert not entity.state[ATTR_IN_PROGRESS]


async def test_firmware_update_downgrade(zha_gateway: Gateway) -> None:
"""Test ZHA update platform - force a firmware downgrade."""
zigpy_device = zigpy_device_mock(zha_gateway)
Expand Down
4 changes: 3 additions & 1 deletion zha/application/platforms/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,9 @@ async def async_install(self, version: str | None) -> None:
except Exception as ex:
self._attr_in_progress = False
self.maybe_emit_state_changed_event()
raise ZHAException(f"Update was not successful: {ex}") from ex
raise ZHAException(
f"Update was not successful: {str(ex) or repr(ex)}"
) from ex

# If the update finished but was not successful, we should also throw an error
if result != Status.SUCCESS:
Expand Down
Loading