mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Exception chaining and wrapping improvements (#39320)
* Remove unnecessary exception re-wraps * Preserve exception chains on re-raise We slap "from cause" to almost all possible cases here. In some cases it could conceivably be better to do "from None" if we really want to hide the cause. However those should be in the minority, and "from cause" should be an improvement over the corresponding raise without a "from" in all cases anyway. The only case where we raise from None here is in plex, where the exception for an original invalid SSL cert is not the root cause for failure to validate a newly fetched one. Follow local convention on exception variable names if there is a consistent one, otherwise `err` to match with majority of codebase. * Fix mistaken re-wrap in homematicip_cloud/hap.py Missed the difference between HmipConnectionError and HmipcConnectionError. * Do not hide original error on plex new cert validation error Original is not the cause for the new one, but showing old in the traceback is useful nevertheless.
This commit is contained in:
parent
d768fd4de9
commit
b4bac0f7a0
@ -150,7 +150,9 @@ async def _load_mfa_module(hass: HomeAssistant, module_name: str) -> types.Modul
|
|||||||
module = importlib.import_module(module_path)
|
module = importlib.import_module(module_path)
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
_LOGGER.error("Unable to load mfa module %s: %s", module_name, err)
|
_LOGGER.error("Unable to load mfa module %s: %s", module_name, err)
|
||||||
raise HomeAssistantError(f"Unable to load mfa module {module_name}: {err}")
|
raise HomeAssistantError(
|
||||||
|
f"Unable to load mfa module {module_name}: {err}"
|
||||||
|
) from err
|
||||||
|
|
||||||
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
||||||
return module
|
return module
|
||||||
|
@ -146,7 +146,9 @@ async def load_auth_provider_module(
|
|||||||
module = importlib.import_module(f"homeassistant.auth.providers.{provider}")
|
module = importlib.import_module(f"homeassistant.auth.providers.{provider}")
|
||||||
except ImportError as err:
|
except ImportError as err:
|
||||||
_LOGGER.error("Unable to load auth provider %s: %s", provider, err)
|
_LOGGER.error("Unable to load auth provider %s: %s", provider, err)
|
||||||
raise HomeAssistantError(f"Unable to load auth provider {provider}: {err}")
|
raise HomeAssistantError(
|
||||||
|
f"Unable to load auth provider {provider}: {err}"
|
||||||
|
) from err
|
||||||
|
|
||||||
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
|
||||||
return module
|
return module
|
||||||
|
@ -71,7 +71,7 @@ class CommandLineAuthProvider(AuthProvider):
|
|||||||
except OSError as err:
|
except OSError as err:
|
||||||
# happens when command doesn't exist or permission is denied
|
# happens when command doesn't exist or permission is denied
|
||||||
_LOGGER.error("Error while authenticating %r: %s", username, err)
|
_LOGGER.error("Error while authenticating %r: %s", username, err)
|
||||||
raise InvalidAuthError
|
raise InvalidAuthError from err
|
||||||
|
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
@ -120,7 +120,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
|
|
||||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||||
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from ex
|
||||||
|
|
||||||
for platform in ABODE_PLATFORMS:
|
for platform in ABODE_PLATFORMS:
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
|
@ -127,6 +127,6 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
InvalidApiKeyError,
|
InvalidApiKeyError,
|
||||||
RequestsExceededError,
|
RequestsExceededError,
|
||||||
) as error:
|
) as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
_LOGGER.debug("Requests remaining: %s", self.accuweather.requests_remaining)
|
_LOGGER.debug("Requests remaining: %s", self.accuweather.requests_remaining)
|
||||||
return {**current, **{ATTR_FORECAST: forecast}}
|
return {**current, **{ATTR_FORECAST: forecast}}
|
||||||
|
@ -33,9 +33,9 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
agent_client = Agent(server_origin, async_get_clientsession(hass))
|
agent_client = Agent(server_origin, async_get_clientsession(hass))
|
||||||
try:
|
try:
|
||||||
await agent_client.update()
|
await agent_client.update()
|
||||||
except AgentError:
|
except AgentError as err:
|
||||||
await agent_client.close()
|
await agent_client.close()
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
if not agent_client.is_available:
|
if not agent_client.is_available:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady
|
||||||
|
@ -125,7 +125,7 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
try:
|
try:
|
||||||
await measurements.update()
|
await measurements.update()
|
||||||
except (AirlyError, ClientConnectorError) as error:
|
except (AirlyError, ClientConnectorError) as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
|
|
||||||
values = measurements.current["values"]
|
values = measurements.current["values"]
|
||||||
index = measurements.current["indexes"][0]
|
index = measurements.current["indexes"][0]
|
||||||
|
@ -227,7 +227,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
try:
|
try:
|
||||||
return await api_coro
|
return await api_coro
|
||||||
except AirVisualError as err:
|
except AirVisualError as err:
|
||||||
raise UpdateFailed(f"Error while retrieving data: {err}")
|
raise UpdateFailed(f"Error while retrieving data: {err}") from err
|
||||||
|
|
||||||
coordinator = DataUpdateCoordinator(
|
coordinator = DataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
@ -263,7 +263,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
include_trends=False,
|
include_trends=False,
|
||||||
)
|
)
|
||||||
except NodeProError as err:
|
except NodeProError as err:
|
||||||
raise UpdateFailed(f"Error while retrieving data: {err}")
|
raise UpdateFailed(f"Error while retrieving data: {err}") from err
|
||||||
|
|
||||||
coordinator = DataUpdateCoordinator(
|
coordinator = DataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
@ -1542,8 +1542,10 @@ async def async_api_initialize_camera_stream(hass, config, directive, context):
|
|||||||
require_ssl=True,
|
require_ssl=True,
|
||||||
require_standard_port=True,
|
require_standard_port=True,
|
||||||
)
|
)
|
||||||
except network.NoURLAvailableError:
|
except network.NoURLAvailableError as err:
|
||||||
raise AlexaInvalidValueError("Failed to find suitable URL to serve to Alexa")
|
raise AlexaInvalidValueError(
|
||||||
|
"Failed to find suitable URL to serve to Alexa"
|
||||||
|
) from err
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"cameraStreams": [
|
"cameraStreams": [
|
||||||
|
@ -208,7 +208,7 @@ async def _configure_almond_for_ha(
|
|||||||
msg = err
|
msg = err
|
||||||
_LOGGER.warning("Unable to configure Almond: %s", msg)
|
_LOGGER.warning("Unable to configure Almond: %s", msg)
|
||||||
await hass.auth.async_remove_refresh_token(refresh_token)
|
await hass.auth.async_remove_refresh_token(refresh_token)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
# Clear all other refresh tokens
|
# Clear all other refresh tokens
|
||||||
for token in list(user.refresh_tokens.values()):
|
for token in list(user.refresh_tokens.values()):
|
||||||
|
@ -300,7 +300,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = ambient
|
hass.data[DOMAIN][DATA_CLIENT][config_entry.entry_id] = ambient
|
||||||
except WebsocketError as err:
|
except WebsocketError as err:
|
||||||
_LOGGER.error("Config entry failed: %s", err)
|
_LOGGER.error("Config entry failed: %s", err)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
hass.bus.async_listen_once(
|
hass.bus.async_listen_once(
|
||||||
EVENT_HOMEASSISTANT_STOP, ambient.client.websocket.disconnect()
|
EVENT_HOMEASSISTANT_STOP, ambient.client.websocket.disconnect()
|
||||||
|
@ -375,8 +375,8 @@ class APIDomainServicesView(HomeAssistantView):
|
|||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
domain, service, data, True, self.context(request)
|
domain, service, data, True, self.context(request)
|
||||||
)
|
)
|
||||||
except (vol.Invalid, ServiceNotFound):
|
except (vol.Invalid, ServiceNotFound) as ex:
|
||||||
raise HTTPBadRequest()
|
raise HTTPBadRequest() from ex
|
||||||
|
|
||||||
return self.json(changed_states)
|
return self.json(changed_states)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ class AsteriskMailbox(Mailbox):
|
|||||||
partial(client.mp3, msgid, sync=True)
|
partial(client.mp3, msgid, sync=True)
|
||||||
)
|
)
|
||||||
except ServerError as err:
|
except ServerError as err:
|
||||||
raise StreamError(err)
|
raise StreamError(err) from err
|
||||||
|
|
||||||
async def async_get_messages(self):
|
async def async_get_messages(self):
|
||||||
"""Return a list of the current messages."""
|
"""Return a list of the current messages."""
|
||||||
|
@ -66,7 +66,7 @@ class AtagDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
if not await self.atag.update():
|
if not await self.atag.update():
|
||||||
raise UpdateFailed("No data received")
|
raise UpdateFailed("No data received")
|
||||||
except AtagException as error:
|
except AtagException as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
return self.atag.report
|
return self.atag.report
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
outlets = dev.outlets()
|
outlets = dev.outlets()
|
||||||
except AtenPEError as exc:
|
except AtenPEError as exc:
|
||||||
_LOGGER.error("Failed to initialize %s:%s: %s", node, serv, str(exc))
|
_LOGGER.error("Failed to initialize %s:%s: %s", node, serv, str(exc))
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from exc
|
||||||
|
|
||||||
switches = []
|
switches = []
|
||||||
async for outlet in outlets:
|
async for outlet in outlets:
|
||||||
|
@ -171,8 +171,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
try:
|
try:
|
||||||
await august_gateway.async_setup(entry.data)
|
await august_gateway.async_setup(entry.data)
|
||||||
return await async_setup_august(hass, entry, august_gateway)
|
return await async_setup_august(hass, entry, august_gateway)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||||
@ -339,7 +339,7 @@ class AugustData(AugustSubscriberMixin):
|
|||||||
device_name = self._get_device_name(device_id)
|
device_name = self._get_device_name(device_id)
|
||||||
if device_name is None:
|
if device_name is None:
|
||||||
device_name = f"DeviceID: {device_id}"
|
device_name = f"DeviceID: {device_id}"
|
||||||
raise HomeAssistantError(f"{device_name}: {err}")
|
raise HomeAssistantError(f"{device_name}: {err}") from err
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ class AugustGateway:
|
|||||||
self._authentication = await self.authenticator.async_authenticate()
|
self._authentication = await self.authenticator.async_authenticate()
|
||||||
except ClientError as ex:
|
except ClientError as ex:
|
||||||
_LOGGER.error("Unable to connect to August service: %s", str(ex))
|
_LOGGER.error("Unable to connect to August service: %s", str(ex))
|
||||||
raise CannotConnect
|
raise CannotConnect from ex
|
||||||
|
|
||||||
if self._authentication.state == AuthenticationState.BAD_PASSWORD:
|
if self._authentication.state == AuthenticationState.BAD_PASSWORD:
|
||||||
raise InvalidAuth
|
raise InvalidAuth
|
||||||
|
@ -170,8 +170,8 @@ def _parse_client_id(client_id):
|
|||||||
try:
|
try:
|
||||||
# parts raises ValueError when port cannot be parsed as int
|
# parts raises ValueError when port cannot be parsed as int
|
||||||
parts.port
|
parts.port
|
||||||
except ValueError:
|
except ValueError as ex:
|
||||||
raise ValueError("Client ID contains invalid port")
|
raise ValueError("Client ID contains invalid port") from ex
|
||||||
|
|
||||||
# Additionally, hostnames
|
# Additionally, hostnames
|
||||||
# MUST be domain names or a loopback interface and
|
# MUST be domain names or a loopback interface and
|
||||||
|
@ -102,9 +102,9 @@ class AwairDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
raise UpdateFailed(err)
|
raise UpdateFailed(err) from err
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise UpdateFailed(err)
|
raise UpdateFailed(err) from err
|
||||||
|
|
||||||
async def _fetch_air_data(self, device):
|
async def _fetch_air_data(self, device):
|
||||||
"""Fetch latest air quality data."""
|
"""Fetch latest air quality data."""
|
||||||
|
@ -186,8 +186,8 @@ class AxisNetworkDevice:
|
|||||||
password=self.config_entry.data[CONF_PASSWORD],
|
password=self.config_entry.data[CONF_PASSWORD],
|
||||||
)
|
)
|
||||||
|
|
||||||
except CannotConnect:
|
except CannotConnect as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
LOGGER.error("Unknown error connecting with Axis device on %s", self.host)
|
LOGGER.error("Unknown error connecting with Axis device on %s", self.host)
|
||||||
@ -271,14 +271,14 @@ async def get_device(hass, host, port, username, password):
|
|||||||
|
|
||||||
return device
|
return device
|
||||||
|
|
||||||
except axis.Unauthorized:
|
except axis.Unauthorized as err:
|
||||||
LOGGER.warning("Connected to device at %s but not registered.", host)
|
LOGGER.warning("Connected to device at %s but not registered.", host)
|
||||||
raise AuthenticationRequired
|
raise AuthenticationRequired from err
|
||||||
|
|
||||||
except (asyncio.TimeoutError, axis.RequestError):
|
except (asyncio.TimeoutError, axis.RequestError) as err:
|
||||||
LOGGER.error("Error connecting to the Axis device at %s", host)
|
LOGGER.error("Error connecting to the Axis device at %s", host)
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
|
||||||
except axis.AxisException:
|
except axis.AxisException as err:
|
||||||
LOGGER.exception("Unknown Axis communication error occurred")
|
LOGGER.exception("Unknown Axis communication error occurred")
|
||||||
raise AuthenticationRequired
|
raise AuthenticationRequired from err
|
||||||
|
@ -26,8 +26,8 @@ def validate_input(hass: core.HomeAssistant, auth):
|
|||||||
"""Validate the user input allows us to connect."""
|
"""Validate the user input allows us to connect."""
|
||||||
try:
|
try:
|
||||||
auth.startup()
|
auth.startup()
|
||||||
except (LoginError, TokenRefreshFailed):
|
except (LoginError, TokenRefreshFailed) as err:
|
||||||
raise InvalidAuth
|
raise InvalidAuth from err
|
||||||
if auth.check_key_required():
|
if auth.check_key_required():
|
||||||
raise Require2FA
|
raise Require2FA
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
"%s. Hint: Check wiring and make sure that the SDO pin is tied to either ground (0x76) or VCC (0x77)",
|
"%s. Hint: Check wiring and make sure that the SDO pin is tied to either ground (0x76) or VCC (0x77)",
|
||||||
error.args[0],
|
error.args[0],
|
||||||
)
|
)
|
||||||
raise PlatformNotReady()
|
raise PlatformNotReady() from error
|
||||||
_LOGGER.error(error)
|
_LOGGER.error(error)
|
||||||
return
|
return
|
||||||
# use custom name if there's any
|
# use custom name if there's any
|
||||||
|
@ -28,15 +28,15 @@ async def _validate_input(data: Dict[str, Any]) -> str:
|
|||||||
version = await bond.version()
|
version = await bond.version()
|
||||||
# call to non-version API is needed to validate authentication
|
# call to non-version API is needed to validate authentication
|
||||||
await bond.devices()
|
await bond.devices()
|
||||||
except ClientConnectionError:
|
except ClientConnectionError as error:
|
||||||
raise InputValidationError("cannot_connect")
|
raise InputValidationError("cannot_connect") from error
|
||||||
except ClientResponseError as error:
|
except ClientResponseError as error:
|
||||||
if error.status == 401:
|
if error.status == 401:
|
||||||
raise InputValidationError("invalid_auth")
|
raise InputValidationError("invalid_auth") from error
|
||||||
raise InputValidationError("unknown")
|
raise InputValidationError("unknown") from error
|
||||||
except Exception:
|
except Exception as error:
|
||||||
_LOGGER.exception("Unexpected exception")
|
_LOGGER.exception("Unexpected exception")
|
||||||
raise InputValidationError("unknown")
|
raise InputValidationError("unknown") from error
|
||||||
|
|
||||||
# Return unique ID from the hub to be stored in the config entry.
|
# Return unique ID from the hub to be stored in the config entry.
|
||||||
bond_id = version.get("bondid")
|
bond_id = version.get("bondid")
|
||||||
|
@ -82,8 +82,8 @@ class BroadlinkDevice:
|
|||||||
await self._async_handle_auth_error()
|
await self._async_handle_auth_error()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except (DeviceOfflineError, OSError):
|
except (DeviceOfflineError, OSError) as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
except BroadlinkException as err:
|
except BroadlinkException as err:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
@ -175,8 +175,8 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
code = self._codes[device][command]
|
code = self._codes[device][command]
|
||||||
except KeyError:
|
except KeyError as err:
|
||||||
raise KeyError("Command not found")
|
raise KeyError("Command not found") from err
|
||||||
|
|
||||||
# For toggle commands, alternate between codes in a list.
|
# For toggle commands, alternate between codes in a list.
|
||||||
if isinstance(code, list):
|
if isinstance(code, list):
|
||||||
@ -187,8 +187,8 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
return data_packet(code), is_toggle_cmd
|
return data_packet(code), is_toggle_cmd
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise ValueError("Invalid code")
|
raise ValueError("Invalid code") from err
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def get_flags(self):
|
def get_flags(self):
|
||||||
|
@ -63,7 +63,7 @@ class BroadlinkUpdateManager(ABC):
|
|||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Disconnected from the device at %s", self.device.api.host[0]
|
"Disconnected from the device at %s", self.device.api.host[0]
|
||||||
)
|
)
|
||||||
raise UpdateFailed(err)
|
raise UpdateFailed(err) from err
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if self.available is False:
|
if self.available is False:
|
||||||
|
@ -82,5 +82,5 @@ class BrotherDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
try:
|
try:
|
||||||
await self.brother.async_update()
|
await self.brother.async_update()
|
||||||
except (ConnectionError, SnmpError, UnsupportedModel) as error:
|
except (ConnectionError, SnmpError, UnsupportedModel) as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
return self.brother.data
|
return self.brother.data
|
||||||
|
@ -539,8 +539,8 @@ class CameraMjpegStream(CameraView):
|
|||||||
if interval < MIN_STREAM_INTERVAL:
|
if interval < MIN_STREAM_INTERVAL:
|
||||||
raise ValueError(f"Stream interval must be be > {MIN_STREAM_INTERVAL}")
|
raise ValueError(f"Stream interval must be be > {MIN_STREAM_INTERVAL}")
|
||||||
return await camera.handle_async_still_stream(request, interval)
|
return await camera.handle_async_still_stream(request, interval)
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise web.HTTPBadRequest()
|
raise web.HTTPBadRequest() from err
|
||||||
|
|
||||||
|
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
|
@ -76,7 +76,7 @@ class CertExpiryDataUpdateCoordinator(DataUpdateCoordinator[datetime]):
|
|||||||
try:
|
try:
|
||||||
timestamp = await get_cert_expiry_timestamp(self.hass, self.host, self.port)
|
timestamp = await get_cert_expiry_timestamp(self.hass, self.host, self.port)
|
||||||
except TemporaryFailure as err:
|
except TemporaryFailure as err:
|
||||||
raise UpdateFailed(err.args[0])
|
raise UpdateFailed(err.args[0]) from err
|
||||||
except ValidationFailure as err:
|
except ValidationFailure as err:
|
||||||
self.cert_error = err
|
self.cert_error = err
|
||||||
self.is_cert_valid = False
|
self.is_cert_valid = False
|
||||||
|
@ -28,16 +28,20 @@ async def get_cert_expiry_timestamp(hass, hostname, port):
|
|||||||
"""Return the certificate's expiration timestamp."""
|
"""Return the certificate's expiration timestamp."""
|
||||||
try:
|
try:
|
||||||
cert = await hass.async_add_executor_job(get_cert, hostname, port)
|
cert = await hass.async_add_executor_job(get_cert, hostname, port)
|
||||||
except socket.gaierror:
|
except socket.gaierror as err:
|
||||||
raise ResolveFailed(f"Cannot resolve hostname: {hostname}")
|
raise ResolveFailed(f"Cannot resolve hostname: {hostname}") from err
|
||||||
except socket.timeout:
|
except socket.timeout as err:
|
||||||
raise ConnectionTimeout(f"Connection timeout with server: {hostname}:{port}")
|
raise ConnectionTimeout(
|
||||||
except ConnectionRefusedError:
|
f"Connection timeout with server: {hostname}:{port}"
|
||||||
raise ConnectionRefused(f"Connection refused by server: {hostname}:{port}")
|
) from err
|
||||||
|
except ConnectionRefusedError as err:
|
||||||
|
raise ConnectionRefused(
|
||||||
|
f"Connection refused by server: {hostname}:{port}"
|
||||||
|
) from err
|
||||||
except ssl.CertificateError as err:
|
except ssl.CertificateError as err:
|
||||||
raise ValidationFailure(err.verify_message)
|
raise ValidationFailure(err.verify_message) from err
|
||||||
except ssl.SSLError as err:
|
except ssl.SSLError as err:
|
||||||
raise ValidationFailure(err.args[0])
|
raise ValidationFailure(err.args[0]) from err
|
||||||
|
|
||||||
ts_seconds = ssl.cert_time_to_seconds(cert["notAfter"])
|
ts_seconds = ssl.cert_time_to_seconds(cert["notAfter"])
|
||||||
return dt.utc_from_timestamp(ts_seconds)
|
return dt.utc_from_timestamp(ts_seconds)
|
||||||
|
@ -225,8 +225,8 @@ class CityBikesNetworks:
|
|||||||
result = network[ATTR_ID]
|
result = network[ATTR_ID]
|
||||||
|
|
||||||
return result
|
return result
|
||||||
except CityBikesRequestError:
|
except CityBikesRequestError as err:
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
finally:
|
finally:
|
||||||
self.networks_loading.release()
|
self.networks_loading.release()
|
||||||
|
|
||||||
@ -251,11 +251,11 @@ class CityBikesNetwork:
|
|||||||
)
|
)
|
||||||
self.stations = network[ATTR_NETWORK][ATTR_STATIONS_LIST]
|
self.stations = network[ATTR_NETWORK][ATTR_STATIONS_LIST]
|
||||||
self.ready.set()
|
self.ready.set()
|
||||||
except CityBikesRequestError:
|
except CityBikesRequestError as err:
|
||||||
if now is not None:
|
if now is not None:
|
||||||
self.ready.clear()
|
self.ready.clear()
|
||||||
else:
|
else:
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
|
|
||||||
|
|
||||||
class CityBikesStation(Entity):
|
class CityBikesStation(Entity):
|
||||||
|
@ -59,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
await account.getAccountBearerToken()
|
await account.getAccountBearerToken()
|
||||||
except client_exceptions.ClientError as exception:
|
except client_exceptions.ClientError as exception:
|
||||||
_LOGGER.error("Error connecting to Control4 account API: %s", exception)
|
_LOGGER.error("Error connecting to Control4 account API: %s", exception)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from exception
|
||||||
except BadCredentials as exception:
|
except BadCredentials as exception:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Error authenticating with Control4 account API, incorrect username or password: %s",
|
"Error authenticating with Control4 account API, incorrect username or password: %s",
|
||||||
|
@ -45,14 +45,14 @@ async def async_setup_entry(
|
|||||||
try:
|
try:
|
||||||
return await director_update_data(hass, entry, CONTROL4_NON_DIMMER_VAR)
|
return await director_update_data(hass, entry, CONTROL4_NON_DIMMER_VAR)
|
||||||
except C4Exception as err:
|
except C4Exception as err:
|
||||||
raise UpdateFailed(f"Error communicating with API: {err}")
|
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||||
|
|
||||||
async def async_update_data_dimmer():
|
async def async_update_data_dimmer():
|
||||||
"""Fetch data from Control4 director for dimmer lights."""
|
"""Fetch data from Control4 director for dimmer lights."""
|
||||||
try:
|
try:
|
||||||
return await director_update_data(hass, entry, CONTROL4_DIMMER_VAR)
|
return await director_update_data(hass, entry, CONTROL4_DIMMER_VAR)
|
||||||
except C4Exception as err:
|
except C4Exception as err:
|
||||||
raise UpdateFailed(f"Error communicating with API: {err}")
|
raise UpdateFailed(f"Error communicating with API: {err}") from err
|
||||||
|
|
||||||
non_dimmer_coordinator = DataUpdateCoordinator(
|
non_dimmer_coordinator = DataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
@ -114,12 +114,12 @@ async def daikin_api_setup(hass, host, key, uuid, password):
|
|||||||
device = await Appliance.factory(
|
device = await Appliance.factory(
|
||||||
host, session, key=key, uuid=uuid, password=password
|
host, session, key=key, uuid=uuid, password=password
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError as err:
|
||||||
_LOGGER.debug("Connection to %s timed out", host)
|
_LOGGER.debug("Connection to %s timed out", host)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
except ClientConnectionError:
|
except ClientConnectionError as err:
|
||||||
_LOGGER.debug("ClientConnectionError to %s", host)
|
_LOGGER.debug("ClientConnectionError to %s", host)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
_LOGGER.error("Unexpected error creating device %s", host)
|
_LOGGER.error("Unexpected error creating device %s", host)
|
||||||
return None
|
return None
|
||||||
|
@ -98,8 +98,8 @@ class DeconzGateway:
|
|||||||
self.async_connection_status_callback,
|
self.async_connection_status_callback,
|
||||||
)
|
)
|
||||||
|
|
||||||
except CannotConnect:
|
except CannotConnect as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
except Exception as err: # pylint: disable=broad-except
|
except Exception as err: # pylint: disable=broad-except
|
||||||
LOGGER.error("Error connecting with deCONZ gateway: %s", err)
|
LOGGER.error("Error connecting with deCONZ gateway: %s", err)
|
||||||
@ -254,10 +254,10 @@ async def get_gateway(
|
|||||||
await deconz.initialize()
|
await deconz.initialize()
|
||||||
return deconz
|
return deconz
|
||||||
|
|
||||||
except errors.Unauthorized:
|
except errors.Unauthorized as err:
|
||||||
LOGGER.warning("Invalid key for deCONZ at %s", config[CONF_HOST])
|
LOGGER.warning("Invalid key for deCONZ at %s", config[CONF_HOST])
|
||||||
raise AuthenticationRequired
|
raise AuthenticationRequired from err
|
||||||
|
|
||||||
except (asyncio.TimeoutError, errors.RequestError):
|
except (asyncio.TimeoutError, errors.RequestError) as err:
|
||||||
LOGGER.error("Error connecting to deCONZ gateway at %s", config[CONF_HOST])
|
LOGGER.error("Error connecting to deCONZ gateway at %s", config[CONF_HOST])
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
@ -58,9 +58,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
deluge_api = DelugeRPCClient(host, port, username, password)
|
deluge_api = DelugeRPCClient(host, port, username, password)
|
||||||
try:
|
try:
|
||||||
deluge_api.connect()
|
deluge_api.connect()
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError as err:
|
||||||
_LOGGER.error("Connection to Deluge Daemon failed")
|
_LOGGER.error("Connection to Deluge Daemon failed")
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
dev = []
|
dev = []
|
||||||
for variable in config[CONF_MONITORED_VARIABLES]:
|
for variable in config[CONF_MONITORED_VARIABLES]:
|
||||||
dev.append(DelugeSensor(variable, deluge_api, name))
|
dev.append(DelugeSensor(variable, deluge_api, name))
|
||||||
|
@ -46,9 +46,9 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
deluge_api = DelugeRPCClient(host, port, username, password)
|
deluge_api = DelugeRPCClient(host, port, username, password)
|
||||||
try:
|
try:
|
||||||
deluge_api.connect()
|
deluge_api.connect()
|
||||||
except ConnectionRefusedError:
|
except ConnectionRefusedError as err:
|
||||||
_LOGGER.error("Connection to Deluge Daemon failed")
|
_LOGGER.error("Connection to Deluge Daemon failed")
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
|
|
||||||
add_entities([DelugeSwitch(deluge_api, name)])
|
add_entities([DelugeSwitch(deluge_api, name)])
|
||||||
|
|
||||||
|
@ -83,12 +83,14 @@ async def async_get_device_automation_platform(
|
|||||||
try:
|
try:
|
||||||
integration = await async_get_integration_with_requirements(hass, domain)
|
integration = await async_get_integration_with_requirements(hass, domain)
|
||||||
platform = integration.get_platform(platform_name)
|
platform = integration.get_platform(platform_name)
|
||||||
except IntegrationNotFound:
|
except IntegrationNotFound as err:
|
||||||
raise InvalidDeviceAutomationConfig(f"Integration '{domain}' not found")
|
raise InvalidDeviceAutomationConfig(
|
||||||
except ImportError:
|
f"Integration '{domain}' not found"
|
||||||
|
) from err
|
||||||
|
except ImportError as err:
|
||||||
raise InvalidDeviceAutomationConfig(
|
raise InvalidDeviceAutomationConfig(
|
||||||
f"Integration '{domain}' does not support device automation {automation_type}s"
|
f"Integration '{domain}' does not support device automation {automation_type}s"
|
||||||
)
|
) from err
|
||||||
|
|
||||||
return platform
|
return platform
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool
|
|||||||
hass.data[DOMAIN]["homecontrol"] = await hass.async_add_executor_job(
|
hass.data[DOMAIN]["homecontrol"] = await hass.async_add_executor_job(
|
||||||
partial(HomeControl, gateway_id=gateway_id, url=mprm_url)
|
partial(HomeControl, gateway_id=gateway_id, url=mprm_url)
|
||||||
)
|
)
|
||||||
except ConnectionError:
|
except ConnectionError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
for platform in PLATFORMS:
|
for platform in PLATFORMS:
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
|
@ -43,8 +43,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
)
|
)
|
||||||
except AccountError:
|
except AccountError:
|
||||||
return False
|
return False
|
||||||
except SessionError:
|
except SessionError as error:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from error
|
||||||
|
|
||||||
if not entry.options:
|
if not entry.options:
|
||||||
hass.config_entries.async_update_entry(
|
hass.config_entries.async_update_entry(
|
||||||
@ -55,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
try:
|
try:
|
||||||
return await hass.async_add_executor_job(dexcom.get_current_glucose_reading)
|
return await hass.async_add_executor_job(dexcom.get_current_glucose_reading)
|
||||||
except SessionError as error:
|
except SessionError as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id] = {
|
hass.data[DOMAIN][entry.entry_id] = {
|
||||||
COORDINATOR: DataUpdateCoordinator(
|
COORDINATOR: DataUpdateCoordinator(
|
||||||
|
@ -59,8 +59,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
await dtv.update()
|
await dtv.update()
|
||||||
except DIRECTVError:
|
except DIRECTVError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
hass.data[DOMAIN][entry.entry_id] = dtv
|
hass.data[DOMAIN][entry.entry_id] = dtv
|
||||||
|
|
||||||
|
@ -182,8 +182,8 @@ async def async_setup_platform(
|
|||||||
factory = UpnpFactory(requester, disable_state_variable_validation=True)
|
factory = UpnpFactory(requester, disable_state_variable_validation=True)
|
||||||
try:
|
try:
|
||||||
upnp_device = await factory.async_create_device(url)
|
upnp_device = await factory.async_create_device(url)
|
||||||
except (asyncio.TimeoutError, aiohttp.ClientError):
|
except (asyncio.TimeoutError, aiohttp.ClientError) as err:
|
||||||
raise PlatformNotReady()
|
raise PlatformNotReady() from err
|
||||||
|
|
||||||
# wrap with DmrDevice
|
# wrap with DmrDevice
|
||||||
dlna_device = DmrDevice(upnp_device, event_handler)
|
dlna_device = DmrDevice(upnp_device, event_handler)
|
||||||
|
@ -132,10 +132,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
"Authorization rejected by DoorBird for %s@%s", username, device_ip
|
"Authorization rejected by DoorBird for %s@%s", username, device_ip
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
except OSError as oserr:
|
except OSError as oserr:
|
||||||
_LOGGER.error("Failed to setup doorbird at %s: %s", device_ip, oserr)
|
_LOGGER.error("Failed to setup doorbird at %s: %s", device_ip, oserr)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from oserr
|
||||||
|
|
||||||
if not status[0]:
|
if not status[0]:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
@ -40,10 +40,10 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
info = await hass.async_add_executor_job(device.info)
|
info = await hass.async_add_executor_job(device.info)
|
||||||
except urllib.error.HTTPError as err:
|
except urllib.error.HTTPError as err:
|
||||||
if err.code == 401:
|
if err.code == 401:
|
||||||
raise InvalidAuth
|
raise InvalidAuth from err
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
except OSError:
|
except OSError as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
|
||||||
if not status[0]:
|
if not status[0]:
|
||||||
raise CannotConnect
|
raise CannotConnect
|
||||||
|
@ -81,7 +81,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
await ebox_data.async_update()
|
await ebox_data.async_update()
|
||||||
except PyEboxError as exp:
|
except PyEboxError as exp:
|
||||||
_LOGGER.error("Failed login: %s", exp)
|
_LOGGER.error("Failed login: %s", exp)
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from exp
|
||||||
|
|
||||||
sensors = []
|
sensors = []
|
||||||
for variable in config[CONF_MONITORED_VARIABLES]:
|
for variable in config[CONF_MONITORED_VARIABLES]:
|
||||||
|
@ -110,7 +110,7 @@ class EbusdData:
|
|||||||
self.value[name] = command_result
|
self.value[name] = command_result
|
||||||
except RuntimeError as err:
|
except RuntimeError as err:
|
||||||
_LOGGER.error(err)
|
_LOGGER.error(err)
|
||||||
raise RuntimeError(err)
|
raise RuntimeError(err) from err
|
||||||
|
|
||||||
def write(self, call):
|
def write(self, call):
|
||||||
"""Call write methon on ebusd."""
|
"""Call write methon on ebusd."""
|
||||||
|
@ -8,8 +8,8 @@ def ecobee_date(date_string):
|
|||||||
"""Validate a date_string as valid for the ecobee API."""
|
"""Validate a date_string as valid for the ecobee API."""
|
||||||
try:
|
try:
|
||||||
datetime.strptime(date_string, "%Y-%m-%d")
|
datetime.strptime(date_string, "%Y-%m-%d")
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise vol.Invalid("Date does not match ecobee date format YYYY-MM-DD")
|
raise vol.Invalid("Date does not match ecobee date format YYYY-MM-DD") from err
|
||||||
return date_string
|
return date_string
|
||||||
|
|
||||||
|
|
||||||
@ -17,6 +17,8 @@ def ecobee_time(time_string):
|
|||||||
"""Validate a time_string as valid for the ecobee API."""
|
"""Validate a time_string as valid for the ecobee API."""
|
||||||
try:
|
try:
|
||||||
datetime.strptime(time_string, "%H:%M:%S")
|
datetime.strptime(time_string, "%H:%M:%S")
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise vol.Invalid("Time does not match ecobee 24-hour time format HH:MM:SS")
|
raise vol.Invalid(
|
||||||
|
"Time does not match ecobee 24-hour time format HH:MM:SS"
|
||||||
|
) from err
|
||||||
return time_string
|
return time_string
|
||||||
|
@ -50,8 +50,8 @@ class EcobeeWeather(WeatherEntity):
|
|||||||
try:
|
try:
|
||||||
forecast = self.weather["forecasts"][index]
|
forecast = self.weather["forecasts"][index]
|
||||||
return forecast[param]
|
return forecast[param]
|
||||||
except (ValueError, IndexError, KeyError):
|
except (IndexError, KeyError) as err:
|
||||||
raise ValueError
|
raise ValueError from err
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -55,8 +55,8 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
|
|
||||||
effects = await api.get_all_patterns()
|
effects = await api.get_all_patterns()
|
||||||
|
|
||||||
except pyeverlights.ConnectionError:
|
except pyeverlights.ConnectionError as err:
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
|
|
||||||
else:
|
else:
|
||||||
lights.append(EverLightsLight(api, pyeverlights.ZONE_1, status, effects))
|
lights.append(EverLightsLight(api, pyeverlights.ZONE_1, status, effects))
|
||||||
|
@ -48,10 +48,10 @@ class FlickConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
try:
|
try:
|
||||||
with async_timeout.timeout(60):
|
with async_timeout.timeout(60):
|
||||||
token = await auth.async_get_access_token()
|
token = await auth.async_get_access_token()
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError as err:
|
||||||
raise CannotConnect()
|
raise CannotConnect() from err
|
||||||
except AuthException:
|
except AuthException as err:
|
||||||
raise InvalidAuth()
|
raise InvalidAuth() from err
|
||||||
else:
|
else:
|
||||||
return token is not None
|
return token is not None
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
hass.data[DOMAIN][entry.entry_id]["client"] = client = await async_get_api(
|
hass.data[DOMAIN][entry.entry_id]["client"] = client = await async_get_api(
|
||||||
entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], session=session
|
entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], session=session
|
||||||
)
|
)
|
||||||
except RequestError:
|
except RequestError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
user_info = await client.user.get_info(include_location_info=True)
|
user_info = await client.user.get_info(include_location_info=True)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
)
|
)
|
||||||
except RequestError as request_error:
|
except RequestError as request_error:
|
||||||
_LOGGER.error("Error connecting to the Flo API: %s", request_error)
|
_LOGGER.error("Error connecting to the Flo API: %s", request_error)
|
||||||
raise CannotConnect
|
raise CannotConnect from request_error
|
||||||
|
|
||||||
user_info = await api.user.get_info()
|
user_info = await api.user.get_info()
|
||||||
a_location_id = user_info["locations"][0]["id"]
|
a_location_id = user_info["locations"][0]["id"]
|
||||||
|
@ -46,7 +46,7 @@ class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
*[self._update_device(), self._update_consumption_data()]
|
*[self._update_device(), self._update_consumption_data()]
|
||||||
)
|
)
|
||||||
except (RequestError) as error:
|
except (RequestError) as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def location_id(self) -> str:
|
def location_id(self) -> str:
|
||||||
|
@ -67,8 +67,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
http_session=http_session,
|
http_session=http_session,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except RequestException:
|
except RequestException as ex:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from ex
|
||||||
except Exception as ex: # pylint: disable=broad-except
|
except Exception as ex: # pylint: disable=broad-except
|
||||||
_LOGGER.error("Invalid credentials for flume: %s", ex)
|
_LOGGER.error("Invalid credentials for flume: %s", ex)
|
||||||
return False
|
return False
|
||||||
|
@ -57,10 +57,10 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
flume_devices = await hass.async_add_executor_job(FlumeDeviceList, flume_auth)
|
flume_devices = await hass.async_add_executor_job(FlumeDeviceList, flume_auth)
|
||||||
except RequestException:
|
except RequestException as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception as err: # pylint: disable=broad-except
|
||||||
raise InvalidAuth
|
raise InvalidAuth from err
|
||||||
if not flume_devices or not flume_devices.device_list:
|
if not flume_devices or not flume_devices.device_list:
|
||||||
raise CannotConnect
|
raise CannotConnect
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ def async_get_api_category(sensor_type):
|
|||||||
if sensor[0] == sensor_type
|
if sensor[0] == sensor_type
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
except StopIteration:
|
except StopIteration as err:
|
||||||
raise ValueError(f"Can't find category sensor type: {sensor_type}")
|
raise ValueError(f"Can't find category sensor type: {sensor_type}") from err
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
|
@ -82,9 +82,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
asyncio.TimeoutError,
|
asyncio.TimeoutError,
|
||||||
FoobotClient.TooManyRequests,
|
FoobotClient.TooManyRequests,
|
||||||
FoobotClient.InternalError,
|
FoobotClient.InternalError,
|
||||||
):
|
) as err:
|
||||||
_LOGGER.exception("Failed to connect to foobot servers")
|
_LOGGER.exception("Failed to connect to foobot servers")
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
except FoobotClient.ClientError:
|
except FoobotClient.ClientError:
|
||||||
_LOGGER.error("Failed to fetch data from foobot servers")
|
_LOGGER.error("Failed to fetch data from foobot servers")
|
||||||
return
|
return
|
||||||
|
@ -49,7 +49,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Connection error occurred during Garmin Connect login request: %s", err
|
"Connection error occurred during Garmin Connect login request: %s", err
|
||||||
)
|
)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
_LOGGER.exception("Unknown error occurred during Garmin Connect login request")
|
_LOGGER.exception("Unknown error occurred during Garmin Connect login request")
|
||||||
return False
|
return False
|
||||||
|
@ -69,7 +69,7 @@ class GiosDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
ClientConnectorError,
|
ClientConnectorError,
|
||||||
InvalidSensorsData,
|
InvalidSensorsData,
|
||||||
) as error:
|
) as error:
|
||||||
raise UpdateFailed(error)
|
raise UpdateFailed(error) from error
|
||||||
if not self.gios.data:
|
if not self.gios.data:
|
||||||
raise UpdateFailed("Invalid sensors data")
|
raise UpdateFailed("Invalid sensors data")
|
||||||
return self.gios.data
|
return self.gios.data
|
||||||
|
@ -121,9 +121,9 @@ class GlancesData:
|
|||||||
self.available = True
|
self.available = True
|
||||||
_LOGGER.debug("Successfully connected to Glances")
|
_LOGGER.debug("Successfully connected to Glances")
|
||||||
|
|
||||||
except exceptions.GlancesApiConnectionError:
|
except exceptions.GlancesApiConnectionError as err:
|
||||||
_LOGGER.debug("Can not connect to Glances")
|
_LOGGER.debug("Can not connect to Glances")
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
self.add_options()
|
self.add_options()
|
||||||
self.set_scan_interval(self.config_entry.options[CONF_SCAN_INTERVAL])
|
self.set_scan_interval(self.config_entry.options[CONF_SCAN_INTERVAL])
|
||||||
|
@ -52,8 +52,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
try:
|
try:
|
||||||
api = get_api(hass, data)
|
api = get_api(hass, data)
|
||||||
await api.get_data()
|
await api.get_data()
|
||||||
except glances_api.exceptions.GlancesApiConnectionError:
|
except glances_api.exceptions.GlancesApiConnectionError as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
|
||||||
|
|
||||||
class GlancesFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
class GlancesFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
|
@ -69,7 +69,9 @@ def get_data_update_coordinator(
|
|||||||
async with async_timeout.timeout(3):
|
async with async_timeout.timeout(3):
|
||||||
return await hass.async_add_executor_job(api.info)
|
return await hass.async_add_executor_job(api.info)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
raise UpdateFailed(f"Error communicating with API: {exception}")
|
raise UpdateFailed(
|
||||||
|
f"Error communicating with API: {exception}"
|
||||||
|
) from exception
|
||||||
|
|
||||||
config_entry_data[DATA_UPDATE_COORDINATOR] = GogoGateDataUpdateCoordinator(
|
config_entry_data[DATA_UPDATE_COORDINATOR] = GogoGateDataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
@ -28,8 +28,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
await AsyncGriddy(
|
await AsyncGriddy(
|
||||||
client_session, settlement_point=data[CONF_LOADZONE]
|
client_session, settlement_point=data[CONF_LOADZONE]
|
||||||
).async_getnow()
|
).async_getnow()
|
||||||
except (asyncio.TimeoutError, ClientError):
|
except (asyncio.TimeoutError, ClientError) as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
|
||||||
# Return info that you want to store in the config entry.
|
# Return info that you want to store in the config entry.
|
||||||
return {"title": f"Load Zone {data[CONF_LOADZONE]}"}
|
return {"title": f"Load Zone {data[CONF_LOADZONE]}"}
|
||||||
|
@ -45,5 +45,5 @@ class GuardianDataUpdateCoordinator(DataUpdateCoordinator[dict]):
|
|||||||
try:
|
try:
|
||||||
resp = await self._api_coro()
|
resp = await self._api_coro()
|
||||||
except GuardianError as err:
|
except GuardianError as err:
|
||||||
raise UpdateFailed(err)
|
raise UpdateFailed(err) from err
|
||||||
return resp["data"]
|
return resp["data"]
|
||||||
|
@ -45,8 +45,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
name, entry.unique_id, address, activity, harmony_conf_file, delay_secs
|
name, entry.unique_id, address, activity, harmony_conf_file, delay_secs
|
||||||
)
|
)
|
||||||
connected_ok = await device.connect()
|
connected_ok = await device.connect()
|
||||||
except (asyncio.TimeoutError, ValueError, AttributeError):
|
except (asyncio.TimeoutError, ValueError, AttributeError) as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
if not connected_ok:
|
if not connected_ok:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady
|
||||||
|
@ -111,7 +111,7 @@ class HassIOPasswordReset(HassIOBaseAuth):
|
|||||||
await provider.async_change_password(
|
await provider.async_change_password(
|
||||||
data[ATTR_USERNAME], data[ATTR_PASSWORD]
|
data[ATTR_USERNAME], data[ATTR_PASSWORD]
|
||||||
)
|
)
|
||||||
except auth_ha.InvalidUser:
|
except auth_ha.InvalidUser as err:
|
||||||
raise HTTPNotFound()
|
raise HTTPNotFound() from err
|
||||||
|
|
||||||
return web.Response(status=HTTP_OK)
|
return web.Response(status=HTTP_OK)
|
||||||
|
@ -75,7 +75,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||||||
except HeosError as error:
|
except HeosError as error:
|
||||||
await controller.disconnect()
|
await controller.disconnect()
|
||||||
_LOGGER.debug("Unable to connect to controller %s: %s", host, error)
|
_LOGGER.debug("Unable to connect to controller %s: %s", host, error)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from error
|
||||||
|
|
||||||
# Disconnect when shutting down
|
# Disconnect when shutting down
|
||||||
async def disconnect_controller(event):
|
async def disconnect_controller(event):
|
||||||
@ -99,7 +99,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||||||
except HeosError as error:
|
except HeosError as error:
|
||||||
await controller.disconnect()
|
await controller.disconnect()
|
||||||
_LOGGER.debug("Unable to retrieve players and sources: %s", error)
|
_LOGGER.debug("Unable to retrieve players and sources: %s", error)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from error
|
||||||
|
|
||||||
controller_manager = ControllerManager(hass, controller)
|
controller_manager = ControllerManager(hass, controller)
|
||||||
await controller_manager.connect_listeners()
|
await controller_manager.connect_listeners()
|
||||||
|
@ -22,8 +22,8 @@ def coerce_ip(value):
|
|||||||
raise vol.Invalid("Must define an IP address")
|
raise vol.Invalid("Must define an IP address")
|
||||||
try:
|
try:
|
||||||
ipaddress.IPv4Network(value)
|
ipaddress.IPv4Network(value)
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise vol.Invalid("Not a valid IP address")
|
raise vol.Invalid("Not a valid IP address") from err
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ async def validate_input(hass: HomeAssistant, user_input):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
client = await connect_client(hass, user_input)
|
client = await connect_client(hass, user_input)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
try:
|
try:
|
||||||
|
|
||||||
def disconnect_callback():
|
def disconnect_callback():
|
||||||
@ -62,7 +62,7 @@ async def validate_input(hass: HomeAssistant, user_input):
|
|||||||
except CannotConnect:
|
except CannotConnect:
|
||||||
client.disconnect_callback = None
|
client.disconnect_callback = None
|
||||||
client.stop()
|
client.stop()
|
||||||
raise CannotConnect
|
raise
|
||||||
else:
|
else:
|
||||||
client.disconnect_callback = None
|
client.disconnect_callback = None
|
||||||
client.stop()
|
client.stop()
|
||||||
|
@ -40,8 +40,8 @@ class TimePattern:
|
|||||||
|
|
||||||
if not (0 <= number <= self.maximum):
|
if not (0 <= number <= self.maximum):
|
||||||
raise vol.Invalid(f"must be a value between 0 and {self.maximum}")
|
raise vol.Invalid(f"must be a value between 0 and {self.maximum}")
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise vol.Invalid("invalid time_pattern value")
|
raise vol.Invalid("invalid time_pattern value") from err
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ class HomematicipHAP:
|
|||||||
self.config_entry.data.get(HMIPC_AUTHTOKEN),
|
self.config_entry.data.get(HMIPC_AUTHTOKEN),
|
||||||
self.config_entry.data.get(HMIPC_NAME),
|
self.config_entry.data.get(HMIPC_NAME),
|
||||||
)
|
)
|
||||||
except HmipcConnectionError:
|
except HmipcConnectionError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
except Exception as err: # pylint: disable=broad-except
|
except Exception as err: # pylint: disable=broad-except
|
||||||
_LOGGER.error("Error connecting with HomematicIP Cloud: %s", err)
|
_LOGGER.error("Error connecting with HomematicIP Cloud: %s", err)
|
||||||
return False
|
return False
|
||||||
@ -247,8 +247,8 @@ class HomematicipHAP:
|
|||||||
try:
|
try:
|
||||||
await home.init(hapid)
|
await home.init(hapid)
|
||||||
await home.get_current_state()
|
await home.get_current_state()
|
||||||
except HmipConnectionError:
|
except HmipConnectionError as err:
|
||||||
raise HmipcConnectionError
|
raise HmipcConnectionError from err
|
||||||
home.on_update(self.async_update)
|
home.on_update(self.async_update)
|
||||||
home.on_create(self.async_create_entity)
|
home.on_create(self.async_create_entity)
|
||||||
hass.loop.create_task(self.async_connect())
|
hass.loop.create_task(self.async_connect())
|
||||||
|
@ -71,7 +71,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
except OSError as msg:
|
except OSError as msg:
|
||||||
# occurs if horizon box is offline
|
# occurs if horizon box is offline
|
||||||
_LOGGER.error("Connection to %s at %s failed: %s", name, host, msg)
|
_LOGGER.error("Connection to %s at %s failed: %s", name, host, msg)
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from msg
|
||||||
|
|
||||||
_LOGGER.info("Connection to %s at %s established", name, host)
|
_LOGGER.info("Connection to %s at %s established", name, host)
|
||||||
|
|
||||||
|
@ -191,4 +191,4 @@ class HpIloData:
|
|||||||
hpilo.IloCommunicationError,
|
hpilo.IloCommunicationError,
|
||||||
hpilo.IloLoginFailed,
|
hpilo.IloLoginFailed,
|
||||||
) as error:
|
) as error:
|
||||||
raise ValueError(f"Unable to init HP ILO, {error}")
|
raise ValueError(f"Unable to init HP ILO, {error}") from error
|
||||||
|
@ -91,11 +91,11 @@ def async_setup_forwarded(app, trusted_proxies):
|
|||||||
forwarded_for_split = list(reversed(forwarded_for_headers[0].split(",")))
|
forwarded_for_split = list(reversed(forwarded_for_headers[0].split(",")))
|
||||||
try:
|
try:
|
||||||
forwarded_for = [ip_address(addr.strip()) for addr in forwarded_for_split]
|
forwarded_for = [ip_address(addr.strip()) for addr in forwarded_for_split]
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Invalid IP address in X-Forwarded-For: %s", forwarded_for_headers[0]
|
"Invalid IP address in X-Forwarded-For: %s", forwarded_for_headers[0]
|
||||||
)
|
)
|
||||||
raise HTTPBadRequest
|
raise HTTPBadRequest from err
|
||||||
|
|
||||||
# Find the last trusted index in the X-Forwarded-For list
|
# Find the last trusted index in the X-Forwarded-For list
|
||||||
forwarded_for_index = 0
|
forwarded_for_index = 0
|
||||||
|
@ -52,7 +52,7 @@ class HomeAssistantView:
|
|||||||
msg = json.dumps(result, cls=JSONEncoder, allow_nan=False).encode("UTF-8")
|
msg = json.dumps(result, cls=JSONEncoder, allow_nan=False).encode("UTF-8")
|
||||||
except (ValueError, TypeError) as err:
|
except (ValueError, TypeError) as err:
|
||||||
_LOGGER.error("Unable to serialize to JSON: %s\n%s", err, result)
|
_LOGGER.error("Unable to serialize to JSON: %s\n%s", err, result)
|
||||||
raise HTTPInternalServerError
|
raise HTTPInternalServerError from err
|
||||||
response = web.Response(
|
response = web.Response(
|
||||||
body=msg,
|
body=msg,
|
||||||
content_type=CONTENT_TYPE_JSON,
|
content_type=CONTENT_TYPE_JSON,
|
||||||
@ -127,12 +127,12 @@ def request_handler_factory(view: HomeAssistantView, handler: Callable) -> Calla
|
|||||||
|
|
||||||
if asyncio.iscoroutine(result):
|
if asyncio.iscoroutine(result):
|
||||||
result = await result
|
result = await result
|
||||||
except vol.Invalid:
|
except vol.Invalid as err:
|
||||||
raise HTTPBadRequest()
|
raise HTTPBadRequest() from err
|
||||||
except exceptions.ServiceNotFound:
|
except exceptions.ServiceNotFound as err:
|
||||||
raise HTTPInternalServerError()
|
raise HTTPInternalServerError() from err
|
||||||
except exceptions.Unauthorized:
|
except exceptions.Unauthorized as err:
|
||||||
raise HTTPUnauthorized()
|
raise HTTPUnauthorized() from err
|
||||||
|
|
||||||
if isinstance(result, web.StreamResponse):
|
if isinstance(result, web.StreamResponse):
|
||||||
# The method handler returned a ready-made Response, how nice of it
|
# The method handler returned a ready-made Response, how nice of it
|
||||||
|
@ -94,9 +94,9 @@ class HueBridge:
|
|||||||
create_config_flow(hass, host)
|
create_config_flow(hass, host)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
except CannotConnect:
|
except CannotConnect as err:
|
||||||
LOGGER.error("Error connecting to the Hue bridge at %s", host)
|
LOGGER.error("Error connecting to the Hue bridge at %s", host)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
LOGGER.exception("Unknown error connecting with Hue bridge at %s", host)
|
LOGGER.exception("Unknown error connecting with Hue bridge at %s", host)
|
||||||
@ -269,18 +269,18 @@ async def authenticate_bridge(hass: core.HomeAssistant, bridge: aiohue.Bridge):
|
|||||||
# Initialize bridge (and validate our username)
|
# Initialize bridge (and validate our username)
|
||||||
await bridge.initialize()
|
await bridge.initialize()
|
||||||
|
|
||||||
except (aiohue.LinkButtonNotPressed, aiohue.Unauthorized):
|
except (aiohue.LinkButtonNotPressed, aiohue.Unauthorized) as err:
|
||||||
raise AuthenticationRequired
|
raise AuthenticationRequired from err
|
||||||
except (
|
except (
|
||||||
asyncio.TimeoutError,
|
asyncio.TimeoutError,
|
||||||
client_exceptions.ClientOSError,
|
client_exceptions.ClientOSError,
|
||||||
client_exceptions.ServerDisconnectedError,
|
client_exceptions.ServerDisconnectedError,
|
||||||
client_exceptions.ContentTypeError,
|
client_exceptions.ContentTypeError,
|
||||||
):
|
) as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
except aiohue.AiohueException:
|
except aiohue.AiohueException as err:
|
||||||
LOGGER.exception("Unknown Hue linking error occurred")
|
LOGGER.exception("Unknown Hue linking error occurred")
|
||||||
raise AuthenticationRequired
|
raise AuthenticationRequired from err
|
||||||
|
|
||||||
|
|
||||||
async def _update_listener(hass, entry):
|
async def _update_listener(hass, entry):
|
||||||
|
@ -159,11 +159,11 @@ async def async_safe_fetch(bridge, fetch_method):
|
|||||||
try:
|
try:
|
||||||
with async_timeout.timeout(4):
|
with async_timeout.timeout(4):
|
||||||
return await bridge.async_request_call(fetch_method)
|
return await bridge.async_request_call(fetch_method)
|
||||||
except aiohue.Unauthorized:
|
except aiohue.Unauthorized as err:
|
||||||
await bridge.handle_unauthorized_error()
|
await bridge.handle_unauthorized_error()
|
||||||
raise UpdateFailed("Unauthorized")
|
raise UpdateFailed("Unauthorized") from err
|
||||||
except (aiohue.AiohueException,) as err:
|
except (aiohue.AiohueException,) as err:
|
||||||
raise UpdateFailed(f"Hue error: {err}")
|
raise UpdateFailed(f"Hue error: {err}") from err
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -61,11 +61,11 @@ class SensorManager:
|
|||||||
return await self.bridge.async_request_call(
|
return await self.bridge.async_request_call(
|
||||||
self.bridge.api.sensors.update
|
self.bridge.api.sensors.update
|
||||||
)
|
)
|
||||||
except Unauthorized:
|
except Unauthorized as err:
|
||||||
await self.bridge.handle_unauthorized_error()
|
await self.bridge.handle_unauthorized_error()
|
||||||
raise UpdateFailed("Unauthorized")
|
raise UpdateFailed("Unauthorized") from err
|
||||||
except AiohueException as err:
|
except AiohueException as err:
|
||||||
raise UpdateFailed(f"Hue error: {err}")
|
raise UpdateFailed(f"Hue error: {err}") from err
|
||||||
|
|
||||||
async def async_register_component(self, platform, async_add_entities):
|
async def async_register_component(self, platform, async_add_entities):
|
||||||
"""Register async_add_entities methods for components."""
|
"""Register async_add_entities methods for components."""
|
||||||
|
@ -128,9 +128,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
shade_data = _async_map_data_by_id(
|
shade_data = _async_map_data_by_id(
|
||||||
(await shades.get_resources())[SHADE_DATA]
|
(await shades.get_resources())[SHADE_DATA]
|
||||||
)
|
)
|
||||||
except HUB_EXCEPTIONS:
|
except HUB_EXCEPTIONS as err:
|
||||||
_LOGGER.error("Connection error to PowerView hub: %s", hub_address)
|
_LOGGER.error("Connection error to PowerView hub: %s", hub_address)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
if not device_info:
|
if not device_info:
|
||||||
_LOGGER.error("Unable to initialize PowerView hub: %s", hub_address)
|
_LOGGER.error("Unable to initialize PowerView hub: %s", hub_address)
|
||||||
|
@ -33,8 +33,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
try:
|
try:
|
||||||
async with async_timeout.timeout(10):
|
async with async_timeout.timeout(10):
|
||||||
device_info = await async_get_device_info(pv_request)
|
device_info = await async_get_device_info(pv_request)
|
||||||
except HUB_EXCEPTIONS:
|
except HUB_EXCEPTIONS as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
if not device_info:
|
if not device_info:
|
||||||
raise CannotConnect
|
raise CannotConnect
|
||||||
|
|
||||||
|
@ -41,16 +41,16 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
try:
|
try:
|
||||||
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
||||||
api = await real_time_api(config_host, config_port)
|
api = await real_time_api(config_host, config_port)
|
||||||
except (IamMeterError, asyncio.TimeoutError):
|
except (IamMeterError, asyncio.TimeoutError) as err:
|
||||||
_LOGGER.error("Device is not ready")
|
_LOGGER.error("Device is not ready")
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from err
|
||||||
|
|
||||||
async def async_update_data():
|
async def async_update_data():
|
||||||
try:
|
try:
|
||||||
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
||||||
return await api.get_data()
|
return await api.get_data()
|
||||||
except (IamMeterError, asyncio.TimeoutError):
|
except (IamMeterError, asyncio.TimeoutError) as err:
|
||||||
raise UpdateFailed
|
raise UpdateFailed from err
|
||||||
|
|
||||||
coordinator = DataUpdateCoordinator(
|
coordinator = DataUpdateCoordinator(
|
||||||
hass,
|
hass,
|
||||||
|
@ -96,7 +96,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> None
|
|||||||
aiohttp.client_exceptions.ClientConnectorError,
|
aiohttp.client_exceptions.ClientConnectorError,
|
||||||
) as aio_exception:
|
) as aio_exception:
|
||||||
_LOGGER.warning("Exception raised while attempting to login: %s", aio_exception)
|
_LOGGER.warning("Exception raised while attempting to login: %s", aio_exception)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from aio_exception
|
||||||
|
|
||||||
systems = await aqualink.get_systems()
|
systems = await aqualink.get_systems()
|
||||||
systems = list(systems.values())
|
systems = list(systems.values())
|
||||||
|
@ -119,9 +119,12 @@ class IcloudAccount:
|
|||||||
api_devices = self.api.devices
|
api_devices = self.api.devices
|
||||||
# Gets device owners infos
|
# Gets device owners infos
|
||||||
user_info = api_devices.response["userInfo"]
|
user_info = api_devices.response["userInfo"]
|
||||||
except (PyiCloudServiceNotActivatedException, PyiCloudNoDevicesException):
|
except (
|
||||||
|
PyiCloudServiceNotActivatedException,
|
||||||
|
PyiCloudNoDevicesException,
|
||||||
|
) as err:
|
||||||
_LOGGER.error("No iCloud device found")
|
_LOGGER.error("No iCloud device found")
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
self._owner_fullname = f"{user_info['firstName']} {user_info['lastName']}"
|
self._owner_fullname = f"{user_info['firstName']} {user_info['lastName']}"
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ class ImageStorageCollection(collection.StorageCollection):
|
|||||||
# Verify we can read the image
|
# Verify we can read the image
|
||||||
try:
|
try:
|
||||||
image = Image.open(uploaded_file.file)
|
image = Image.open(uploaded_file.file)
|
||||||
except UnidentifiedImageError:
|
except UnidentifiedImageError as err:
|
||||||
raise vol.Invalid("Unable to identify image file")
|
raise vol.Invalid("Unable to identify image file") from err
|
||||||
|
|
||||||
# Reset content
|
# Reset content
|
||||||
uploaded_file.file.seek(0)
|
uploaded_file.file.seek(0)
|
||||||
@ -170,8 +170,8 @@ class ImageServeView(HomeAssistantView):
|
|||||||
parts = image_size.split("x", 1)
|
parts = image_size.split("x", 1)
|
||||||
width = int(parts[0])
|
width = int(parts[0])
|
||||||
height = int(parts[1])
|
height = int(parts[1])
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError) as err:
|
||||||
raise web.HTTPBadRequest
|
raise web.HTTPBadRequest from err
|
||||||
|
|
||||||
if not width or width != height or width not in VALID_SIZES:
|
if not width or width != height or width not in VALID_SIZES:
|
||||||
raise web.HTTPBadRequest
|
raise web.HTTPBadRequest
|
||||||
|
@ -324,22 +324,22 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||||||
try:
|
try:
|
||||||
write_api.write(bucket=bucket, record=json)
|
write_api.write(bucket=bucket, record=json)
|
||||||
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
||||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||||
except ApiException as exc:
|
except ApiException as exc:
|
||||||
if exc.status == CODE_INVALID_INPUTS:
|
if exc.status == CODE_INVALID_INPUTS:
|
||||||
raise ValueError(WRITE_ERROR % (json, exc))
|
raise ValueError(WRITE_ERROR % (json, exc)) from exc
|
||||||
raise ConnectionError(CLIENT_ERROR_V2 % exc)
|
raise ConnectionError(CLIENT_ERROR_V2 % exc) from exc
|
||||||
|
|
||||||
def query_v2(query, _=None):
|
def query_v2(query, _=None):
|
||||||
"""Query V2 influx."""
|
"""Query V2 influx."""
|
||||||
try:
|
try:
|
||||||
return query_api.query(query)
|
return query_api.query(query)
|
||||||
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
||||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||||
except ApiException as exc:
|
except ApiException as exc:
|
||||||
if exc.status == CODE_INVALID_INPUTS:
|
if exc.status == CODE_INVALID_INPUTS:
|
||||||
raise ValueError(QUERY_ERROR % (query, exc))
|
raise ValueError(QUERY_ERROR % (query, exc)) from exc
|
||||||
raise ConnectionError(CLIENT_ERROR_V2 % exc)
|
raise ConnectionError(CLIENT_ERROR_V2 % exc) from exc
|
||||||
|
|
||||||
def close_v2():
|
def close_v2():
|
||||||
"""Close V2 influx client."""
|
"""Close V2 influx client."""
|
||||||
@ -399,11 +399,11 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||||||
exceptions.InfluxDBServerError,
|
exceptions.InfluxDBServerError,
|
||||||
OSError,
|
OSError,
|
||||||
) as exc:
|
) as exc:
|
||||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||||
except exceptions.InfluxDBClientError as exc:
|
except exceptions.InfluxDBClientError as exc:
|
||||||
if exc.code == CODE_INVALID_INPUTS:
|
if exc.code == CODE_INVALID_INPUTS:
|
||||||
raise ValueError(WRITE_ERROR % (json, exc))
|
raise ValueError(WRITE_ERROR % (json, exc)) from exc
|
||||||
raise ConnectionError(CLIENT_ERROR_V1 % exc)
|
raise ConnectionError(CLIENT_ERROR_V1 % exc) from exc
|
||||||
|
|
||||||
def query_v1(query, database=None):
|
def query_v1(query, database=None):
|
||||||
"""Query V1 influx."""
|
"""Query V1 influx."""
|
||||||
@ -414,11 +414,11 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||||||
exceptions.InfluxDBServerError,
|
exceptions.InfluxDBServerError,
|
||||||
OSError,
|
OSError,
|
||||||
) as exc:
|
) as exc:
|
||||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||||
except exceptions.InfluxDBClientError as exc:
|
except exceptions.InfluxDBClientError as exc:
|
||||||
if exc.code == CODE_INVALID_INPUTS:
|
if exc.code == CODE_INVALID_INPUTS:
|
||||||
raise ValueError(QUERY_ERROR % (query, exc))
|
raise ValueError(QUERY_ERROR % (query, exc)) from exc
|
||||||
raise ConnectionError(CLIENT_ERROR_V1 % exc)
|
raise ConnectionError(CLIENT_ERROR_V1 % exc) from exc
|
||||||
|
|
||||||
def close_v1():
|
def close_v1():
|
||||||
"""Close the V1 Influx client."""
|
"""Close the V1 Influx client."""
|
||||||
|
@ -147,7 +147,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
influx = get_influx_connection(config, test_read=True)
|
influx = get_influx_connection(config, test_read=True)
|
||||||
except ConnectionError as exc:
|
except ConnectionError as exc:
|
||||||
_LOGGER.error(exc)
|
_LOGGER.error(exc)
|
||||||
raise PlatformNotReady()
|
raise PlatformNotReady() from exc
|
||||||
|
|
||||||
entities = []
|
entities = []
|
||||||
if CONF_QUERIES_FLUX in config:
|
if CONF_QUERIES_FLUX in config:
|
||||||
|
@ -173,8 +173,8 @@ def normalize_byte_entry_to_int(entry: [int, bytes, str]):
|
|||||||
raise ValueError("Not a valid hex code")
|
raise ValueError("Not a valid hex code")
|
||||||
try:
|
try:
|
||||||
entry = unhexlify(entry)
|
entry = unhexlify(entry)
|
||||||
except HexError:
|
except HexError as err:
|
||||||
raise ValueError("Not a valid hex code")
|
raise ValueError("Not a valid hex code") from err
|
||||||
return int.from_bytes(entry, byteorder="big")
|
return int.from_bytes(entry, byteorder="big")
|
||||||
|
|
||||||
|
|
||||||
@ -184,8 +184,8 @@ def add_device_override(config_data, new_override):
|
|||||||
address = str(Address(new_override[CONF_ADDRESS]))
|
address = str(Address(new_override[CONF_ADDRESS]))
|
||||||
cat = normalize_byte_entry_to_int(new_override[CONF_CAT])
|
cat = normalize_byte_entry_to_int(new_override[CONF_CAT])
|
||||||
subcat = normalize_byte_entry_to_int(new_override[CONF_SUBCAT])
|
subcat = normalize_byte_entry_to_int(new_override[CONF_SUBCAT])
|
||||||
except ValueError:
|
except ValueError as err:
|
||||||
raise ValueError("Incorrect values")
|
raise ValueError("Incorrect values") from err
|
||||||
|
|
||||||
overrides = config_data.get(CONF_OVERRIDE, [])
|
overrides = config_data.get(CONF_OVERRIDE, [])
|
||||||
curr_override = {}
|
curr_override = {}
|
||||||
|
@ -107,9 +107,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
except IHAuthenticationError:
|
except IHAuthenticationError:
|
||||||
_LOGGER.error("Invalid username or password")
|
_LOGGER.error("Invalid username or password")
|
||||||
return
|
return
|
||||||
except IHConnectionError:
|
except IHConnectionError as ex:
|
||||||
_LOGGER.error("Error connecting to the %s server", device_type)
|
_LOGGER.error("Error connecting to the %s server", device_type)
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from ex
|
||||||
|
|
||||||
ih_devices = controller.get_devices()
|
ih_devices = controller.get_devices()
|
||||||
if ih_devices:
|
if ih_devices:
|
||||||
@ -199,7 +199,7 @@ class IntesisAC(ClimateEntity):
|
|||||||
await self._controller.connect()
|
await self._controller.connect()
|
||||||
except IHConnectionError as ex:
|
except IHConnectionError as ex:
|
||||||
_LOGGER.error("Exception connecting to IntesisHome: %s", ex)
|
_LOGGER.error("Exception connecting to IntesisHome: %s", ex)
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady from ex
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -121,7 +121,7 @@ class IPPDataUpdateCoordinator(DataUpdateCoordinator[IPPPrinter]):
|
|||||||
try:
|
try:
|
||||||
return await self.ipp.printer()
|
return await self.ipp.printer()
|
||||||
except IPPError as error:
|
except IPPError as error:
|
||||||
raise UpdateFailed(f"Invalid response from API: {error}")
|
raise UpdateFailed(f"Invalid response from API: {error}") from error
|
||||||
|
|
||||||
|
|
||||||
class IPPEntity(Entity):
|
class IPPEntity(Entity):
|
||||||
|
@ -174,8 +174,8 @@ class IslamicPrayerClient:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
await self.hass.async_add_executor_job(self.get_new_prayer_times)
|
await self.hass.async_add_executor_job(self.get_new_prayer_times)
|
||||||
except (exceptions.InvalidResponseError, ConnError):
|
except (exceptions.InvalidResponseError, ConnError) as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
await self.async_update()
|
await self.async_update()
|
||||||
self.config_entry.add_update_listener(self.async_options_updated)
|
self.config_entry.add_update_listener(self.async_options_updated)
|
||||||
|
@ -98,7 +98,7 @@ def _fetch_isy_configuration(
|
|||||||
webroot=webroot,
|
webroot=webroot,
|
||||||
)
|
)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise InvalidAuth(err.args[0])
|
raise InvalidAuth(err.args[0]) from err
|
||||||
|
|
||||||
return Configuration(log=_LOGGER, xml=isy_conn.get_config())
|
return Configuration(log=_LOGGER, xml=isy_conn.get_config())
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||||||
return False
|
return False
|
||||||
except aiohttp.ClientError as error:
|
except aiohttp.ClientError as error:
|
||||||
_LOGGER.error("Could not reach the JuiceNet API %s", error)
|
_LOGGER.error("Could not reach the JuiceNet API %s", error)
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from error
|
||||||
|
|
||||||
if not juicenet.devices:
|
if not juicenet.devices:
|
||||||
_LOGGER.error("No JuiceNet devices found for this account")
|
_LOGGER.error("No JuiceNet devices found for this account")
|
||||||
|
@ -28,10 +28,10 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||||||
await juicenet.get_devices()
|
await juicenet.get_devices()
|
||||||
except TokenError as error:
|
except TokenError as error:
|
||||||
_LOGGER.error("Token Error %s", error)
|
_LOGGER.error("Token Error %s", error)
|
||||||
raise InvalidAuth
|
raise InvalidAuth from error
|
||||||
except aiohttp.ClientError as error:
|
except aiohttp.ClientError as error:
|
||||||
_LOGGER.error("Error connecting %s", error)
|
_LOGGER.error("Error connecting %s", error)
|
||||||
raise CannotConnect
|
raise CannotConnect from error
|
||||||
|
|
||||||
# Return info that you want to store in the config entry.
|
# Return info that you want to store in the config entry.
|
||||||
return {"title": "JuiceNet"}
|
return {"title": "JuiceNet"}
|
||||||
|
@ -186,8 +186,8 @@ class KonnectedFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
try:
|
try:
|
||||||
status = await get_status(self.hass, host, port)
|
status = await get_status(self.hass, host, port)
|
||||||
self.data[CONF_ID] = status.get("chipId", status["mac"].replace(":", ""))
|
self.data[CONF_ID] = status.get("chipId", status["mac"].replace(":", ""))
|
||||||
except (CannotConnect, KeyError):
|
except (CannotConnect, KeyError) as err:
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
else:
|
else:
|
||||||
self.data[CONF_MODEL] = status.get("model", KONN_MODEL)
|
self.data[CONF_MODEL] = status.get("model", KONN_MODEL)
|
||||||
self.data[CONF_ACCESS_TOKEN] = "".join(
|
self.data[CONF_ACCESS_TOKEN] = "".join(
|
||||||
|
@ -390,4 +390,4 @@ async def get_status(hass, host, port):
|
|||||||
|
|
||||||
except client.ClientError as err:
|
except client.ClientError as err:
|
||||||
_LOGGER.error("Exception trying to get panel status: %s", err)
|
_LOGGER.error("Exception trying to get panel status: %s", err)
|
||||||
raise CannotConnect
|
raise CannotConnect from err
|
||||||
|
@ -148,8 +148,8 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
)
|
)
|
||||||
await luftdaten.async_update()
|
await luftdaten.async_update()
|
||||||
hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = luftdaten
|
hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = luftdaten
|
||||||
except LuftdatenError:
|
except LuftdatenError as err:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from err
|
||||||
|
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
|
hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
|
||||||
|
@ -103,9 +103,9 @@ class MediaExtractor:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
all_media = ydl.extract_info(self.get_media_url(), process=False)
|
all_media = ydl.extract_info(self.get_media_url(), process=False)
|
||||||
except DownloadError:
|
except DownloadError as err:
|
||||||
# This exception will be logged by youtube-dl itself
|
# This exception will be logged by youtube-dl itself
|
||||||
raise MEDownloadException()
|
raise MEDownloadException() from err
|
||||||
|
|
||||||
if "entries" in all_media:
|
if "entries" in all_media:
|
||||||
_LOGGER.warning("Playlists are not supported, looking for the first video")
|
_LOGGER.warning("Playlists are not supported, looking for the first video")
|
||||||
@ -123,9 +123,9 @@ class MediaExtractor:
|
|||||||
try:
|
try:
|
||||||
ydl.params["format"] = query
|
ydl.params["format"] = query
|
||||||
requested_stream = ydl.process_ie_result(selected_media, download=False)
|
requested_stream = ydl.process_ie_result(selected_media, download=False)
|
||||||
except (ExtractorError, DownloadError):
|
except (ExtractorError, DownloadError) as err:
|
||||||
_LOGGER.error("Could not extract stream for the query: %s", query)
|
_LOGGER.error("Could not extract stream for the query: %s", query)
|
||||||
raise MEQueryException()
|
raise MEQueryException() from err
|
||||||
|
|
||||||
return requested_stream["url"]
|
return requested_stream["url"]
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ class MetDataUpdateCoordinator(DataUpdateCoordinator):
|
|||||||
try:
|
try:
|
||||||
return await self.weather.fetch_data()
|
return await self.weather.fetch_data()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise UpdateFailed(f"Update failed: {err}")
|
raise UpdateFailed(f"Update failed: {err}") from err
|
||||||
|
|
||||||
def track_home(self):
|
def track_home(self):
|
||||||
"""Start tracking changes to HA home setting."""
|
"""Start tracking changes to HA home setting."""
|
||||||
|
@ -253,7 +253,7 @@ class MikrotikData:
|
|||||||
socket.timeout,
|
socket.timeout,
|
||||||
) as api_error:
|
) as api_error:
|
||||||
_LOGGER.error("Mikrotik %s connection error %s", self._host, api_error)
|
_LOGGER.error("Mikrotik %s connection error %s", self._host, api_error)
|
||||||
raise CannotConnect
|
raise CannotConnect from api_error
|
||||||
except librouteros.exceptions.ProtocolError as api_error:
|
except librouteros.exceptions.ProtocolError as api_error:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Mikrotik %s failed to retrieve data. cmd=[%s] Error: %s",
|
"Mikrotik %s failed to retrieve data. cmd=[%s] Error: %s",
|
||||||
@ -367,8 +367,8 @@ class MikrotikHub:
|
|||||||
api = await self.hass.async_add_executor_job(
|
api = await self.hass.async_add_executor_job(
|
||||||
get_api, self.hass, self.config_entry.data
|
get_api, self.hass, self.config_entry.data
|
||||||
)
|
)
|
||||||
except CannotConnect:
|
except CannotConnect as api_error:
|
||||||
raise ConfigEntryNotReady
|
raise ConfigEntryNotReady from api_error
|
||||||
except LoginError:
|
except LoginError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -415,5 +415,5 @@ def get_api(hass, entry):
|
|||||||
) as api_error:
|
) as api_error:
|
||||||
_LOGGER.error("Mikrotik %s error: %s", entry[CONF_HOST], api_error)
|
_LOGGER.error("Mikrotik %s error: %s", entry[CONF_HOST], api_error)
|
||||||
if "invalid user name or password" in str(api_error):
|
if "invalid user name or password" in str(api_error):
|
||||||
raise LoginError
|
raise LoginError from api_error
|
||||||
raise CannotConnect
|
raise CannotConnect from api_error
|
||||||
|
@ -219,7 +219,7 @@ async def webhook_call_service(hass, config_entry, data):
|
|||||||
config_entry.data[ATTR_DEVICE_NAME],
|
config_entry.data[ATTR_DEVICE_NAME],
|
||||||
ex,
|
ex,
|
||||||
)
|
)
|
||||||
raise HTTPBadRequest()
|
raise HTTPBadRequest() from ex
|
||||||
|
|
||||||
return empty_okay_response()
|
return empty_okay_response()
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user