mirror of
https://github.com/home-assistant/core.git
synced 2026-05-22 00:10:16 +01:00
Add pylint checker for exception translation validation (#171453)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,8 +81,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: AirOSConfigEntry) -> boo
|
||||
) as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
except AirOSKeyDataMissingError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryError("key_data_missing") from err
|
||||
except Exception as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryError("unknown") from err
|
||||
|
||||
airos_class: type[AirOS8 | AirOS6] = (
|
||||
|
||||
@@ -91,6 +91,7 @@ class AmazonDevicesCoordinator(DataUpdateCoordinator[dict[str, AmazonDevice]]):
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except CannotAuthenticate as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
|
||||
@@ -82,7 +82,7 @@ rules:
|
||||
comment: |
|
||||
This integration does not have any entities that should disabled by default.
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues:
|
||||
|
||||
@@ -67,7 +67,7 @@ rules:
|
||||
comment: |
|
||||
Only one entity type (device_tracker) is created, making this not applicable.
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow:
|
||||
status: todo
|
||||
|
||||
@@ -51,6 +51,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: S3ConfigEntry) -> bool:
|
||||
translation_key="invalid_bucket_name",
|
||||
) from err
|
||||
except ValueError as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_endpoint_url",
|
||||
|
||||
@@ -72,7 +72,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: This integration does not use icons.
|
||||
|
||||
@@ -75,11 +75,13 @@ def handle_backup_errors[_R, **P](
|
||||
err.message,
|
||||
exc_info=True,
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(
|
||||
f"Error during backup operation in {func.__name__}:"
|
||||
f" Status {err.status_code}, message: {err.message}"
|
||||
) from err
|
||||
except ServiceRequestError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(
|
||||
f"Timeout during backup operation in {func.__name__}"
|
||||
) from err
|
||||
@@ -90,6 +92,7 @@ def handle_backup_errors[_R, **P](
|
||||
err,
|
||||
exc_info=True,
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(
|
||||
f"Error during backup operation in {func.__name__}: {err}"
|
||||
) from err
|
||||
@@ -118,6 +121,7 @@ class AzureStorageBackupAgent(BackupAgent):
|
||||
"""Download a backup file."""
|
||||
blob = await self._find_blob_by_backup_id(backup_id)
|
||||
if blob is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
download_stream = await self._client.download_blob(blob.name)
|
||||
return download_stream.chunks()
|
||||
@@ -155,6 +159,7 @@ class AzureStorageBackupAgent(BackupAgent):
|
||||
"""Delete a backup file."""
|
||||
blob = await self._find_blob_by_backup_id(backup_id)
|
||||
if blob is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
await self._client.delete_blob(blob.name)
|
||||
|
||||
@@ -181,6 +186,7 @@ class AzureStorageBackupAgent(BackupAgent):
|
||||
"""Return a backup."""
|
||||
blob = await self._find_blob_by_backup_id(backup_id)
|
||||
if blob is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
return AgentBackup.from_dict(json.loads(blob.metadata["backup_metadata"]))
|
||||
|
||||
@@ -89,6 +89,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: BackblazeConfigEntry) ->
|
||||
translation_key="cannot_connect",
|
||||
) from err
|
||||
except exception.MissingAccountData as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
|
||||
@@ -96,7 +96,7 @@ rules:
|
||||
entity-translations:
|
||||
status: exempt
|
||||
comment: This integration does not have entities.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: This integration does not use icons.
|
||||
|
||||
@@ -169,6 +169,7 @@ class BlinkCamera(CoordinatorEntity[BlinkUpdateCoordinator], Camera):
|
||||
try:
|
||||
await self._camera.save_recent_clips(output_dir=file_path)
|
||||
except OSError as err:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
str(err),
|
||||
translation_domain=DOMAIN,
|
||||
@@ -190,6 +191,7 @@ class BlinkCamera(CoordinatorEntity[BlinkUpdateCoordinator], Camera):
|
||||
try:
|
||||
await self._camera.video_to_file(filename)
|
||||
except OSError as err:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
str(err),
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -183,6 +183,7 @@ class BSBLANClimate(BSBLanCircuitEntity, ClimateEntity):
|
||||
try:
|
||||
await self.coordinator.client.thermostat(**data, circuit=self._circuit)
|
||||
except BSBLANError as err:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise HomeAssistantError(
|
||||
"An error occurred while updating the BSBLAN device",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -94,7 +94,7 @@ rules:
|
||||
entity-translations:
|
||||
status: exempt
|
||||
comment: This integration does not have entities.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: This integration does not use icons.
|
||||
|
||||
@@ -65,6 +65,7 @@ async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str,
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except aiocomelit_exceptions.CannotAuthenticate as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise InvalidAuth(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_authenticate",
|
||||
|
||||
@@ -353,6 +353,7 @@ class EcovacsVacuum(
|
||||
if self._capability.clean.action.area is None:
|
||||
info = self._device.device_info
|
||||
name = info.get("nick", info["name"])
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ServiceValidationError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="vacuum_send_command_area_not_supported",
|
||||
|
||||
@@ -88,7 +88,7 @@ rules:
|
||||
entity-translations:
|
||||
status: exempt
|
||||
comment: This integration does not create its own entities.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: This integration does not create its own entities.
|
||||
|
||||
@@ -364,6 +364,7 @@ class ESPHomeManager:
|
||||
response_dict = {"response": response}
|
||||
|
||||
except TemplateError as ex:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise HomeAssistantError(
|
||||
f"Error rendering response template: {ex}"
|
||||
) from ex
|
||||
|
||||
@@ -63,7 +63,7 @@ rules:
|
||||
comment: |
|
||||
This integration does not have many entities. All of them are fundamental.
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues: todo
|
||||
|
||||
@@ -67,6 +67,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: FritzConfigEntry) -> boo
|
||||
"X_AVM-DE_UPnP1" in avm_wrapper.connection.services
|
||||
and not (await avm_wrapper.async_get_upnp_configuration())["NewEnable"]
|
||||
):
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("Missing UPnP configuration")
|
||||
|
||||
await avm_wrapper.async_config_entry_first_refresh()
|
||||
|
||||
@@ -100,6 +100,7 @@ class GoogleDriveBackupAgent(BackupAgent):
|
||||
try:
|
||||
await self._client.async_upload_backup(wrapped_open_stream, backup)
|
||||
except (GoogleDriveApiError, HomeAssistantError, TimeoutError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(f"Failed to upload backup: {err}") from err
|
||||
|
||||
async def async_list_backups(self, **kwargs: Any) -> list[AgentBackup]:
|
||||
@@ -107,6 +108,7 @@ class GoogleDriveBackupAgent(BackupAgent):
|
||||
try:
|
||||
return await self._client.async_list_backups()
|
||||
except (GoogleDriveApiError, HomeAssistantError, TimeoutError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(f"Failed to list backups: {err}") from err
|
||||
|
||||
async def async_get_backup(
|
||||
@@ -119,6 +121,7 @@ class GoogleDriveBackupAgent(BackupAgent):
|
||||
for backup in backups:
|
||||
if backup.backup_id == backup_id:
|
||||
return backup
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
async def async_download_backup(
|
||||
@@ -139,7 +142,9 @@ class GoogleDriveBackupAgent(BackupAgent):
|
||||
stream = await self._client.async_download(file_id)
|
||||
return ChunkAsyncStreamIterator(stream)
|
||||
except (GoogleDriveApiError, HomeAssistantError, TimeoutError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(f"Failed to download backup: {err}") from err
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
async def async_delete_backup(
|
||||
@@ -160,5 +165,7 @@ class GoogleDriveBackupAgent(BackupAgent):
|
||||
_LOGGER.debug("Deleted backup_id: %s", backup_id)
|
||||
return
|
||||
except (GoogleDriveApiError, HomeAssistantError, TimeoutError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(f"Failed to delete backup: {err}") from err
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
@@ -84,6 +84,7 @@ async def _async_handle_upload(call: ServiceCall) -> ServiceResponse:
|
||||
|
||||
scopes = config_entry.data["token"]["scope"].split(" ")
|
||||
if UPLOAD_SCOPE not in scopes:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="missing_upload_permission",
|
||||
|
||||
@@ -56,7 +56,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues:
|
||||
|
||||
@@ -109,6 +109,7 @@ class HabiticaBaseNotifyEntity(HabiticaBase, NotifyEntity):
|
||||
try:
|
||||
await self._send_message(message)
|
||||
except NotAuthorizedError as e:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="send_message_forbidden",
|
||||
@@ -118,6 +119,7 @@ class HabiticaBaseNotifyEntity(HabiticaBase, NotifyEntity):
|
||||
},
|
||||
) from e
|
||||
except NotFoundError as e:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="send_message_not_found",
|
||||
|
||||
@@ -266,6 +266,7 @@ class HomeConnectAirConditioningEntity(HomeConnectEntity, ClimateEntity):
|
||||
value=BSH_POWER_ON,
|
||||
)
|
||||
except HomeConnectError as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="power_on",
|
||||
|
||||
@@ -59,7 +59,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues: todo
|
||||
|
||||
@@ -50,12 +50,14 @@ def homevolt_exception_handler[_HomevoltEntityT: HomevoltEntity, **_P](
|
||||
translation_key="auth_failed",
|
||||
) from error
|
||||
except HomevoltConnectionError as error:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="communication_error",
|
||||
translation_placeholders={"error": str(error)},
|
||||
) from error
|
||||
except HomevoltError as error:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="unknown_error",
|
||||
|
||||
@@ -44,6 +44,7 @@ class HWEnergyDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceResponseEntry]
|
||||
data = await self.api.combined()
|
||||
|
||||
except RequestError as ex:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise UpdateFailed(
|
||||
ex, translation_domain=DOMAIN, translation_key="communication_error"
|
||||
) from ex
|
||||
@@ -60,6 +61,7 @@ class HWEnergyDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceResponseEntry]
|
||||
self.config_entry.entry_id
|
||||
)
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise UpdateFailed(
|
||||
ex, translation_domain=DOMAIN, translation_key="api_disabled"
|
||||
) from ex
|
||||
|
||||
@@ -62,7 +62,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow:
|
||||
status: exempt
|
||||
|
||||
@@ -94,7 +94,7 @@ rules:
|
||||
entity-translations:
|
||||
status: exempt
|
||||
comment: This integration does not have entities.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: This integration does not use icons.
|
||||
|
||||
@@ -62,7 +62,7 @@ rules:
|
||||
comment: >
|
||||
The device class is a service. When removed, entities are removed as well.
|
||||
diagnostics: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow:
|
||||
status: todo
|
||||
|
||||
@@ -73,6 +73,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: InComfortConfigEntry) ->
|
||||
except InvalidHeaterList as exc:
|
||||
raise NoHeaters from exc
|
||||
except InvalidGateway as exc:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("Incorrect credentials") from exc
|
||||
except ClientResponseError as exc:
|
||||
if exc.status == 404:
|
||||
|
||||
@@ -78,11 +78,15 @@ class InComfortDataCoordinator(DataUpdateCoordinator[InComfortData]):
|
||||
for heater in self.incomfort_data.heaters:
|
||||
await heater.update()
|
||||
except TimeoutError as exc:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed("Timeout error") from exc
|
||||
except ClientResponseError as exc:
|
||||
if exc.status == 401:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryError("Incorrect credentials") from exc
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(exc.message) from exc
|
||||
except InvalidHeaterList as exc:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(exc.message) from exc
|
||||
return self.incomfort_data
|
||||
|
||||
@@ -60,7 +60,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues:
|
||||
|
||||
@@ -60,7 +60,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: done
|
||||
|
||||
@@ -29,6 +29,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: IsraelRailConfigEntry) -
|
||||
try:
|
||||
await hass.async_add_executor_job(train_schedule.query, start, destination)
|
||||
except Exception as e:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="request_timeout",
|
||||
|
||||
@@ -115,6 +115,7 @@ async def async_attach_trigger(
|
||||
try:
|
||||
trigger_config = TRIGGER_TRIGGER_SCHEMA(trigger_config)
|
||||
except vol.Invalid as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise InvalidDeviceAutomationConfig(f"{err}") from err
|
||||
|
||||
return await trigger.async_attach_trigger(
|
||||
|
||||
@@ -66,7 +66,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
@@ -105,6 +105,7 @@ class ThinQEntity(CoordinatorEntity[DeviceDataUpdateCoordinator]):
|
||||
except ThinQAPIException as exc:
|
||||
if on_fail_method:
|
||||
on_fail_method()
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
exc.message, translation_domain=DOMAIN, translation_key=exc.code
|
||||
) from exc
|
||||
|
||||
@@ -44,8 +44,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: LiebherrConfigEntry) ->
|
||||
try:
|
||||
devices = await client.get_devices()
|
||||
except LiebherrAuthenticationError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("Invalid API key") from err
|
||||
except LiebherrConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(f"Failed to connect to Liebherr API: {err}") from err
|
||||
|
||||
# Create a coordinator for each device (may be empty if no devices)
|
||||
|
||||
@@ -58,8 +58,10 @@ class LiebherrCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
try:
|
||||
await self.client.get_device(self.device_id)
|
||||
except LiebherrAuthenticationError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("Invalid API key") from err
|
||||
except LiebherrConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
f"Failed to connect to device {self.device_id}: {err}"
|
||||
) from err
|
||||
@@ -69,12 +71,15 @@ class LiebherrCoordinator(DataUpdateCoordinator[DeviceState]):
|
||||
try:
|
||||
return await self.client.get_device_state(self.device_id)
|
||||
except LiebherrAuthenticationError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("API key is no longer valid") from err
|
||||
except LiebherrTimeoutError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(
|
||||
f"Timeout communicating with device {self.device_id}"
|
||||
) from err
|
||||
except LiebherrConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(
|
||||
f"Error communicating with device {self.device_id}"
|
||||
) from err
|
||||
|
||||
@@ -15,6 +15,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Local file from a config entry."""
|
||||
file_path: str = entry.options[CONF_FILE_PATH]
|
||||
if not await hass.async_add_executor_job(check_file_path_access, file_path):
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="not_readable_path",
|
||||
|
||||
@@ -77,6 +77,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: LunatoneConfigEntry) ->
|
||||
await coordinator_info.async_config_entry_first_refresh()
|
||||
|
||||
if info_api.data is None or info_api.serial_number is None:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryError(
|
||||
translation_domain=DOMAIN, translation_key="missing_device_info"
|
||||
)
|
||||
|
||||
@@ -422,6 +422,7 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
||||
},
|
||||
)
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
"Invalid alarm code provided",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -165,6 +165,7 @@ class MieleFan(MieleEntity, FanEntity):
|
||||
try:
|
||||
await self.api.send_action(self._device_id, {POWER_ON: True})
|
||||
except ClientResponseError as ex:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="set_state_error",
|
||||
@@ -182,6 +183,7 @@ class MieleFan(MieleEntity, FanEntity):
|
||||
try:
|
||||
await self.api.send_action(self._device_id, {POWER_OFF: True})
|
||||
except ClientResponseError as ex:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="set_state_error",
|
||||
|
||||
@@ -60,7 +60,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues:
|
||||
|
||||
@@ -291,6 +291,7 @@ async def async_check_config_schema(
|
||||
message = conf_util.format_schema_error(
|
||||
hass, exc, domain, config, integration.documentation
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
message,
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -156,6 +156,7 @@ async def async_publish(
|
||||
) -> None:
|
||||
"""Publish message to a MQTT topic."""
|
||||
if not mqtt_config_entry_enabled(hass):
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise HomeAssistantError(
|
||||
f"Cannot publish to topic '{topic}', MQTT is not enabled",
|
||||
translation_key="mqtt_not_setup_cannot_publish",
|
||||
@@ -281,6 +282,7 @@ def async_subscribe_internal(
|
||||
try:
|
||||
mqtt_data = hass.data[DATA_MQTT]
|
||||
except KeyError as exc:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise HomeAssistantError(
|
||||
f"Cannot subscribe to topic '{topic}', make sure MQTT is set up correctly",
|
||||
translation_key="mqtt_not_setup_cannot_subscribe",
|
||||
@@ -289,6 +291,7 @@ def async_subscribe_internal(
|
||||
) from exc
|
||||
client = mqtt_data.client
|
||||
if not mqtt_config_entry_enabled(hass):
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise HomeAssistantError(
|
||||
f"Cannot subscribe to topic '{topic}', MQTT is not enabled",
|
||||
translation_key="mqtt_not_setup_cannot_subscribe",
|
||||
|
||||
@@ -73,6 +73,7 @@ class SubscriptionID:
|
||||
|
||||
subscription_id = self._next_id
|
||||
if subscription_id > MAX_28BIT:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise HomeAssistantError(
|
||||
"MQTT Subscription ID limit reached. "
|
||||
"Cannot generate more IDs to subscribe",
|
||||
|
||||
@@ -50,6 +50,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NASwebConfigEntry) -> bo
|
||||
)
|
||||
if not await webio_api.refresh_device_info():
|
||||
_LOGGER.error("[%s] Refresh device info failed", entry.data[CONF_HOST])
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_internal_error",
|
||||
translation_placeholders={"support_email": SUPPORT_EMAIL},
|
||||
@@ -57,6 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NASwebConfigEntry) -> bo
|
||||
webio_serial = webio_api.get_serial_number()
|
||||
if webio_serial is None:
|
||||
_LOGGER.error("[%s] Serial number not available", entry.data[CONF_HOST])
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_internal_error",
|
||||
translation_placeholders={"support_email": SUPPORT_EMAIL},
|
||||
@@ -65,6 +67,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: NASwebConfigEntry) -> bo
|
||||
_LOGGER.error(
|
||||
"[%s] Serial number doesn't match config entry", entry.data[CONF_HOST]
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(translation_key="config_entry_error_serial_mismatch")
|
||||
|
||||
coordinator = NASwebCoordinator(
|
||||
@@ -76,12 +79,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: NASwebConfigEntry) -> bo
|
||||
webhook_url = nasweb_data.get_webhook_url(hass)
|
||||
if not await webio_api.status_subscription(webhook_url, True):
|
||||
_LOGGER.error("Failed to subscribe for status updates from webio")
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_internal_error",
|
||||
translation_placeholders={"support_email": SUPPORT_EMAIL},
|
||||
)
|
||||
if not await nasweb_data.notify_coordinator.check_connection(webio_serial):
|
||||
_LOGGER.error("Did not receive status from device")
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_no_status_update",
|
||||
translation_placeholders={"support_email": SUPPORT_EMAIL},
|
||||
@@ -91,10 +96,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: NASwebConfigEntry) -> bo
|
||||
f"[{entry.data[CONF_HOST]}] Check connection reached timeout"
|
||||
) from error
|
||||
except AuthError as error:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_invalid_authentication"
|
||||
) from error
|
||||
except NoURLAvailableError as error:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-domain-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_key="config_entry_error_missing_internal_url"
|
||||
) from error
|
||||
|
||||
@@ -66,7 +66,7 @@ rules:
|
||||
entity-translations:
|
||||
status: exempt
|
||||
comment: Entities use device name as entity name.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: No entity icons are used.
|
||||
|
||||
@@ -160,6 +160,7 @@ class NFAndroidTVNotificationService(BaseNotificationService):
|
||||
auth=imagedata.get(ATTR_IMAGE_AUTH),
|
||||
)
|
||||
else:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
"Invalid image provided",
|
||||
translation_domain=DOMAIN,
|
||||
@@ -182,6 +183,7 @@ class NFAndroidTVNotificationService(BaseNotificationService):
|
||||
auth=icondata.get(ATTR_ICON_AUTH),
|
||||
)
|
||||
else:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
"Invalid Icon provided",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -52,6 +52,7 @@ class NintendoUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
try:
|
||||
return await self.api.update()
|
||||
except InvalidOAuthConfigurationException as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
|
||||
@@ -57,7 +57,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: |
|
||||
|
||||
@@ -65,7 +65,7 @@ rules:
|
||||
PR #170135.
|
||||
entity-disabled-by-default: todo
|
||||
entity-translations: todo
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: todo
|
||||
reconfiguration-flow: todo
|
||||
repair-issues:
|
||||
|
||||
@@ -66,7 +66,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues: todo
|
||||
|
||||
@@ -81,6 +81,7 @@ def handle_backup_errors[_R, **P](
|
||||
return await func(self, *args, **kwargs)
|
||||
except AuthenticationError as err:
|
||||
self._entry.async_start_reauth(self._hass)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Authentication error") from err
|
||||
except OneDriveException as err:
|
||||
_LOGGER.error(
|
||||
@@ -89,12 +90,14 @@ def handle_backup_errors[_R, **P](
|
||||
err,
|
||||
)
|
||||
_LOGGER.debug("Full error: %s", err, exc_info=True)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Backup operation failed") from err
|
||||
except TimeoutError as err:
|
||||
_LOGGER.error(
|
||||
"Error during backup in %s: Timeout",
|
||||
func.__name__,
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Backup operation timed out") from err
|
||||
|
||||
return wrapper
|
||||
@@ -183,6 +186,7 @@ class OneDriveBackupAgent(BackupAgent):
|
||||
),
|
||||
)
|
||||
except HashMismatchError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(
|
||||
"Hash validation failed, backup file might be corrupt"
|
||||
) from err
|
||||
@@ -292,4 +296,5 @@ class OneDriveBackupAgent(BackupAgent):
|
||||
if backup := metadata_files.get(backup_id):
|
||||
return backup
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
@@ -81,6 +81,7 @@ def handle_backup_errors[_R, **P](
|
||||
return await func(self, *args, **kwargs)
|
||||
except AuthenticationError as err:
|
||||
self._entry.async_start_reauth(self._hass)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Authentication error") from err
|
||||
except OneDriveException as err:
|
||||
_LOGGER.error(
|
||||
@@ -89,12 +90,14 @@ def handle_backup_errors[_R, **P](
|
||||
err,
|
||||
)
|
||||
_LOGGER.debug("Full error: %s", err, exc_info=True)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Backup operation failed") from err
|
||||
except TimeoutError as err:
|
||||
_LOGGER.error(
|
||||
"Error during backup in %s: Timeout",
|
||||
func.__name__,
|
||||
)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError("Backup operation timed out") from err
|
||||
|
||||
return wrapper
|
||||
@@ -177,6 +180,7 @@ class OneDriveBackupAgent(BackupAgent):
|
||||
),
|
||||
)
|
||||
except HashMismatchError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupAgentError(
|
||||
"Hash validation failed, backup file might be corrupt"
|
||||
) from err
|
||||
@@ -280,4 +284,5 @@ class OneDriveBackupAgent(BackupAgent):
|
||||
if backup := metadata_files.get(backup_id):
|
||||
return backup
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BackupNotFound(f"Backup {backup_id} not found")
|
||||
|
||||
@@ -57,7 +57,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow:
|
||||
status: exempt
|
||||
|
||||
@@ -64,6 +64,7 @@ class OpenRGBCoordinator(DataUpdateCoordinator[dict[str, Device]]):
|
||||
DEFAULT_CLIENT_NAME,
|
||||
)
|
||||
except CONNECTION_ERRORS as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect",
|
||||
|
||||
@@ -111,6 +111,7 @@ class OpowerCoordinator(DataUpdateCoordinator[dict[str, OpowerData]]):
|
||||
raise ConfigEntryAuthFailed from err
|
||||
except CannotConnect as err:
|
||||
_LOGGER.error("Error during login: %s", err)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(f"Error during login: {err}") from err
|
||||
|
||||
try:
|
||||
|
||||
@@ -65,7 +65,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: todo
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues:
|
||||
|
||||
@@ -48,10 +48,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: PeblarConfigEntry) -> bo
|
||||
system_information = await peblar.system_information()
|
||||
api = await peblar.rest_api(enable=True, access_mode=AccessMode.READ_WRITE)
|
||||
except PeblarConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady("Could not connect to Peblar charger") from err
|
||||
except PeblarAuthenticationError as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
except PeblarError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
"Unknown error occurred while connecting to Peblar charger"
|
||||
) from err
|
||||
|
||||
@@ -64,15 +64,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: PooldoseConfigEntry) ->
|
||||
try:
|
||||
client_status = await client.connect()
|
||||
except TimeoutError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
f"Timeout connecting to PoolDose device: {err}"
|
||||
) from err
|
||||
except (ConnectionError, OSError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
f"Failed to connect to PoolDose device: {err}"
|
||||
) from err
|
||||
|
||||
if client_status != RequestStatus.SUCCESS:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
f"Failed to create PoolDose client while initialization: {client_status}"
|
||||
)
|
||||
|
||||
@@ -49,18 +49,22 @@ class PooldoseCoordinator(DataUpdateCoordinator[StructuredValuesDict]):
|
||||
try:
|
||||
status, instant_values = await self.client.instant_values_structured()
|
||||
except TimeoutError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(
|
||||
f"Timeout fetching data from PoolDose device: {err}"
|
||||
) from err
|
||||
except (ConnectionError, OSError) as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(
|
||||
f"Failed to connect to PoolDose device while fetching data: {err}"
|
||||
) from err
|
||||
|
||||
if status != RequestStatus.SUCCESS:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(f"API returned status: {status}")
|
||||
|
||||
if not instant_values:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed("No data received from API")
|
||||
|
||||
_LOGGER.debug("Instant values structured: %s", instant_values)
|
||||
|
||||
@@ -58,12 +58,14 @@ class PTDevicesCoordinator(DataUpdateCoordinator[PTDevicesResponseData]):
|
||||
try:
|
||||
data = await self.interface.get_data()
|
||||
except aioptdevices.PTDevicesRequestError as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except aioptdevices.PTDevicesUnauthorizedError as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_access_token",
|
||||
|
||||
@@ -52,7 +52,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues: done
|
||||
|
||||
@@ -74,6 +74,7 @@ async def async_setup_entry(
|
||||
await host.async_init()
|
||||
except (UserNotAdmin, CredentialsInvalidError, PasswordIncompatible) as err:
|
||||
await host.stop()
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(err) from err
|
||||
except (
|
||||
ReolinkException,
|
||||
|
||||
@@ -88,12 +88,15 @@ class ReolinkDeviceCoordinator(ReolinkCoordinator):
|
||||
self._host.credential_errors += 1
|
||||
if self._host.credential_errors >= NUM_CRED_ERRORS:
|
||||
await self._host.stop()
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(err) from err
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(str(err)) from err
|
||||
except LoginPrivacyModeError:
|
||||
pass # HTTP API is shutdown when privacy mode is active
|
||||
except ReolinkError as err:
|
||||
self._host.credential_errors = 0
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(str(err)) from err
|
||||
|
||||
self._host.credential_errors = 0
|
||||
@@ -167,6 +170,7 @@ class ReolinkFirmwareCoordinator(ReolinkCoordinator):
|
||||
)
|
||||
return
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(
|
||||
"Error checking Reolink firmware update"
|
||||
f" from {self._host.api.nvr_name}, "
|
||||
|
||||
@@ -171,6 +171,7 @@ class ReolinkHost:
|
||||
translation_placeholders={"name": self._config_entry.title},
|
||||
)
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise PasswordIncompatible(
|
||||
"Reolink password contains incompatible special character or "
|
||||
"is too long, please change the password to only contain characters: "
|
||||
@@ -192,9 +193,11 @@ class ReolinkHost:
|
||||
await self._api.get_host_data()
|
||||
|
||||
if self._api.mac_address is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ReolinkSetupException("Could not get mac address")
|
||||
|
||||
if not self._api.is_admin:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UserNotAdmin(
|
||||
f"User '{self._api.username}' has authorization level "
|
||||
f"'{self._api.user_level}', only admin users can change camera settings"
|
||||
@@ -739,6 +742,7 @@ class ReolinkHost:
|
||||
self._base_url = get_url(self._hass, prefer_external=True)
|
||||
except NoURLAvailableError as err:
|
||||
self.unregister_webhook()
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ReolinkWebhookException(
|
||||
f"Error registering URL for webhook {event_id}: "
|
||||
"HomeAssistant URL is not available"
|
||||
|
||||
@@ -63,6 +63,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
if item.identifier is not None:
|
||||
identifier = item.identifier.split("|", 6)
|
||||
if identifier[0] != "FILE":
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise Unresolvable(f"Unknown media item '{item.identifier}'.")
|
||||
|
||||
_, config_entry_id, channel_str, stream_res, filename, start_time, end_time = (
|
||||
@@ -172,6 +173,7 @@ class ReolinkVODMediaSource(MediaSource):
|
||||
event,
|
||||
)
|
||||
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise Unresolvable(f"Unknown media item '{item.identifier}' during browsing.")
|
||||
|
||||
async def _async_generate_root(self) -> BrowseMediaSource:
|
||||
|
||||
@@ -62,6 +62,7 @@ def get_host(hass: HomeAssistant, config_entry_id: str) -> ReolinkHost:
|
||||
config_entry_id
|
||||
)
|
||||
if config_entry is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise Unresolvable(
|
||||
f"Could not find Reolink config entry id '{config_entry_id}'."
|
||||
)
|
||||
|
||||
@@ -95,6 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) ->
|
||||
prefer_cache=False,
|
||||
)
|
||||
except RoborockInvalidCredentials as err:
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ConfigEntryAuthFailed(
|
||||
"Invalid credentials",
|
||||
translation_domain=DOMAIN,
|
||||
@@ -117,6 +118,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) ->
|
||||
) from err
|
||||
except RoborockException as err:
|
||||
_LOGGER.debug("Failed to get Roborock home data: %s", err)
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ConfigEntryNotReady(
|
||||
"Failed to get Roborock home data",
|
||||
translation_domain=DOMAIN,
|
||||
@@ -176,6 +178,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: RoborockConfigEntry) ->
|
||||
len(v1_coords) + len(a01_coords) + len(b01_q7_coords) + len(b01_q10_coords) == 0
|
||||
and enabled_devices
|
||||
):
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ConfigEntryNotReady(
|
||||
"No devices were able to successfully setup",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -161,6 +161,7 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceState | None]):
|
||||
_LOGGER.info("Home discovery skipped while device is busy/cleaning")
|
||||
except RoborockException as err:
|
||||
_LOGGER.debug("Failed to get maps: %s", err)
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="map_failure",
|
||||
|
||||
@@ -62,7 +62,7 @@ rules:
|
||||
status: exempt
|
||||
comment: There are no noisy entities.
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: todo
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: done
|
||||
|
||||
@@ -43,6 +43,7 @@ async def async_validate_trigger_config(
|
||||
device = async_get_device_entry_by_device_id(hass, device_id)
|
||||
async_get_client_by_device_entry(hass, device)
|
||||
except ValueError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise InvalidDeviceAutomationConfig(err) from err
|
||||
|
||||
return config
|
||||
|
||||
@@ -39,6 +39,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: LeilSaunaConfigEntry) ->
|
||||
try:
|
||||
client = await SaunumClient.create(host)
|
||||
except (SaunumConnectionError, SaunumTimeoutError) as exc:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(f"Error connecting to {host}: {exc}") from exc
|
||||
|
||||
entry.async_on_unload(client.async_close)
|
||||
|
||||
@@ -111,7 +111,7 @@ rules:
|
||||
status: exempt
|
||||
comment: |
|
||||
This integration does not have entities.
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations:
|
||||
status: exempt
|
||||
comment: |
|
||||
|
||||
@@ -401,6 +401,7 @@ class ShellyBlockCoordinator(ShellyCoordinatorBase[BlockDevice]):
|
||||
"""Fetch data."""
|
||||
if self.sleep_period:
|
||||
# Sleeping device, no point polling it, just mark it unavailable
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_error_sleeping_device",
|
||||
@@ -670,6 +671,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
|
||||
|
||||
if self.sleep_period:
|
||||
# Sleeping device, no point polling it, just mark it unavailable
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_error_sleeping_device",
|
||||
|
||||
@@ -344,6 +344,7 @@ class RpcUpdateEntity(ShellyRpcAttributeEntity, UpdateEntity):
|
||||
translation_placeholders={"device": self.coordinator.name},
|
||||
) from err
|
||||
except RpcCallError as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="ota_update_rpc_error",
|
||||
|
||||
@@ -69,12 +69,14 @@ class SMADataUpdateCoordinator(DataUpdateCoordinator[SMACoordinatorData]):
|
||||
SmaConnectionException,
|
||||
) as err:
|
||||
await self.async_close_sma_session()
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except SmaAuthenticationException as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
@@ -89,12 +91,14 @@ class SMADataUpdateCoordinator(DataUpdateCoordinator[SMACoordinatorData]):
|
||||
SmaReadException,
|
||||
SmaConnectionException,
|
||||
) as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_connect",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
except SmaAuthenticationException as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_auth",
|
||||
|
||||
@@ -48,7 +48,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
@@ -80,6 +80,7 @@ class SnooSwitch(SnooDescriptionEntity, SwitchEntity):
|
||||
True,
|
||||
)
|
||||
except SnooCommandException as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="switch_on_failed",
|
||||
@@ -96,6 +97,7 @@ class SnooSwitch(SnooDescriptionEntity, SwitchEntity):
|
||||
False,
|
||||
)
|
||||
except SnooCommandException as err:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="switch_off_failed",
|
||||
|
||||
@@ -86,6 +86,7 @@ class SolarLogBasicDataCoordinator(DataUpdateCoordinator[SolarlogData]):
|
||||
translation_key="auth_failed",
|
||||
) from ex
|
||||
except SolarLogUpdateError as ex:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_failed",
|
||||
@@ -153,6 +154,7 @@ class SolarLogDeviceDataCoordinator(DataUpdateCoordinator[dict[int, InverterData
|
||||
translation_key="auth_failed",
|
||||
) from ex
|
||||
except (SolarLogConnectionError, SolarLogUpdateError) as ex:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_failed",
|
||||
@@ -251,6 +253,7 @@ class SolarLogLongtimeDataCoordinator(DataUpdateCoordinator[EnergyData]):
|
||||
translation_key="auth_failed",
|
||||
) from ex
|
||||
except (SolarLogConnectionError, SolarLogUpdateError) as ex:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_failed",
|
||||
|
||||
@@ -86,6 +86,7 @@ async def async_setup_entry(
|
||||
},
|
||||
) from e
|
||||
except OpendataTransportError as e:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise ConfigEntryError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="invalid_data",
|
||||
|
||||
@@ -96,6 +96,7 @@ class TedeeApiCoordinator(DataUpdateCoordinator[dict[int, TedeeLock]]):
|
||||
try:
|
||||
await update_fn()
|
||||
except TedeeLocalAuthException as ex:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="authentication_failed",
|
||||
|
||||
@@ -916,6 +916,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: TelegramBotConfigEntry)
|
||||
try:
|
||||
await bot.get_me()
|
||||
except InvalidToken as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed("Invalid API token for Telegram Bot.") from err
|
||||
except TelegramError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
@@ -86,6 +86,7 @@ class TeslaFleetCableLockEntity(TeslaFleetVehicleEntity, LockEntity):
|
||||
|
||||
async def async_lock(self, **kwargs: Any) -> None:
|
||||
"""Charge cable Lock cannot be manually locked."""
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
"Insert cable to lock",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -87,6 +87,7 @@ class TeslemetryMetadataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
except (InvalidToken, SubscriptionRequired, LoginRequired) as e:
|
||||
raise ConfigEntryAuthFailed from e
|
||||
except RETRY_EXCEPTIONS as e:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_failed",
|
||||
@@ -94,6 +95,7 @@ class TeslemetryMetadataCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
retry_after=_get_retry_after(e),
|
||||
) from e
|
||||
except TeslaFleetError as e:
|
||||
# pylint: disable-next=home-assistant-exception-placeholder-mismatch
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="update_failed",
|
||||
|
||||
@@ -140,6 +140,7 @@ class TeslemetryCableLockEntity(TeslemetryRootEntity, LockEntity):
|
||||
|
||||
async def async_lock(self, **kwargs: Any) -> None:
|
||||
"""Charge cable Lock cannot be manually locked."""
|
||||
# pylint: disable-next=home-assistant-exception-message-with-translation
|
||||
raise ServiceValidationError(
|
||||
"Insert cable to lock",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -72,7 +72,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
@@ -54,7 +54,7 @@ rules:
|
||||
comment: |
|
||||
Speed sensors change so frequently that disabling by default may be appropriate.
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
@@ -51,10 +51,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: UnifiAccessConfigEntry)
|
||||
try:
|
||||
await client.authenticate()
|
||||
except ApiAuthError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(
|
||||
f"Authentication failed for UniFi Access at {entry.data[CONF_HOST]}"
|
||||
) from err
|
||||
except ApiConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryNotReady(
|
||||
f"Unable to connect to UniFi Access at {entry.data[CONF_HOST]}"
|
||||
) from err
|
||||
|
||||
@@ -197,12 +197,16 @@ class UnifiAccessCoordinator(DataUpdateCoordinator[UnifiAccessData]):
|
||||
self.client.get_emergency_status(),
|
||||
)
|
||||
except ApiAuthError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(f"Authentication failed: {err}") from err
|
||||
except ApiConnectionError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(f"Error connecting to API: {err}") from err
|
||||
except ApiError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||
except TimeoutError as err:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed("Timeout communicating with UniFi Access API") from err
|
||||
|
||||
previous_lock_rules = self.data.door_lock_rules.copy() if self.data else {}
|
||||
|
||||
@@ -84,6 +84,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: UFPConfigEntry) -> bool:
|
||||
except NotAuthorized as err:
|
||||
data_service.auth_retries += 1
|
||||
if data_service.auth_retries > AUTH_RETRIES:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(err) from err
|
||||
raise ConfigEntryNotReady from err
|
||||
except (TimeoutError, ClientError, ServerDisconnectedError) as err:
|
||||
|
||||
@@ -107,7 +107,9 @@ def _get_month_start_end(start: datetime) -> tuple[datetime, datetime]:
|
||||
def _bad_identifier(identifier: str, err: Exception | None = None) -> NoReturn:
|
||||
msg = f"Unexpected identifier: {identifier}"
|
||||
if err is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BrowseError(msg)
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BrowseError(msg) from err
|
||||
|
||||
|
||||
@@ -377,6 +379,7 @@ class ProtectMediaSource(MediaSource):
|
||||
_bad_identifier(f"{data.api.bootstrap.nvr.id}:{subtype}:{event_id}", err)
|
||||
|
||||
if event.start is None or event.end is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BrowseError("Event is still ongoing")
|
||||
|
||||
return await self._build_event(data, event, thumbnail_only)
|
||||
@@ -787,6 +790,7 @@ class ProtectMediaSource(MediaSource):
|
||||
if camera_id != "all":
|
||||
camera = data.api.bootstrap.cameras.get(camera_id)
|
||||
if camera is None:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise BrowseError(f"Unknown Camera ID: {camera_id}")
|
||||
name = camera.name or camera.market_name or camera.type
|
||||
is_doorbell = camera.feature_flags.is_doorbell
|
||||
|
||||
@@ -15,6 +15,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: UptimeRobotConfigEntry)
|
||||
"""Set up UptimeRobot from a config entry."""
|
||||
key: str = entry.data[CONF_API_KEY]
|
||||
if key.startswith(("ur", "m")):
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(
|
||||
"Wrong API key type detected, use the 'main' API key"
|
||||
)
|
||||
|
||||
@@ -48,8 +48,10 @@ class UptimeRobotDataUpdateCoordinator(
|
||||
try:
|
||||
response = await self.api.async_get_monitors()
|
||||
except UptimeRobotAuthenticationException as exception:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise ConfigEntryAuthFailed(exception) from exception
|
||||
except UptimeRobotException as exception:
|
||||
# pylint: disable-next=home-assistant-exception-not-translated
|
||||
raise UpdateFailed(exception) from exception
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
||||
@@ -55,7 +55,7 @@ rules:
|
||||
entity-device-class: todo
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: todo
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: done
|
||||
repair-issues:
|
||||
|
||||
@@ -64,14 +64,17 @@ async def async_setup_entry(
|
||||
try:
|
||||
await manager.login()
|
||||
except VeSyncLoginError as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN, translation_key="invalid_auth"
|
||||
) from err
|
||||
except VeSyncServerError as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN, translation_key="server_error"
|
||||
) from err
|
||||
except VeSyncAPIResponseError as err:
|
||||
# pylint: disable-next=home-assistant-exception-translation-key-missing
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN, translation_key="api_response_error"
|
||||
) from err
|
||||
|
||||
@@ -54,7 +54,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: todo
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
@@ -63,7 +63,7 @@ rules:
|
||||
entity-device-class: done
|
||||
entity-disabled-by-default: done
|
||||
entity-translations: done
|
||||
exception-translations: done
|
||||
exception-translations: todo
|
||||
icon-translations: done
|
||||
reconfiguration-flow: todo
|
||||
repair-issues: todo
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user