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
204 changed files with 550 additions and 518 deletions
|
@ -150,7 +150,9 @@ async def _load_mfa_module(hass: HomeAssistant, module_name: str) -> types.Modul
|
|||
module = importlib.import_module(module_path)
|
||||
except ImportError as 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"):
|
||||
return module
|
||||
|
|
|
@ -146,7 +146,9 @@ async def load_auth_provider_module(
|
|||
module = importlib.import_module(f"homeassistant.auth.providers.{provider}")
|
||||
except ImportError as 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"):
|
||||
return module
|
||||
|
|
|
@ -71,7 +71,7 @@ class CommandLineAuthProvider(AuthProvider):
|
|||
except OSError as err:
|
||||
# happens when command doesn't exist or permission is denied
|
||||
_LOGGER.error("Error while authenticating %r: %s", username, err)
|
||||
raise InvalidAuthError
|
||||
raise InvalidAuthError from err
|
||||
|
||||
if process.returncode != 0:
|
||||
_LOGGER.error(
|
||||
|
|
|
@ -120,7 +120,7 @@ async def async_setup_entry(hass, config_entry):
|
|||
|
||||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from ex
|
||||
|
||||
for platform in ABODE_PLATFORMS:
|
||||
hass.async_create_task(
|
||||
|
|
|
@ -127,6 +127,6 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
InvalidApiKeyError,
|
||||
RequestsExceededError,
|
||||
) as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
_LOGGER.debug("Requests remaining: %s", self.accuweather.requests_remaining)
|
||||
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))
|
||||
try:
|
||||
await agent_client.update()
|
||||
except AgentError:
|
||||
except AgentError as err:
|
||||
await agent_client.close()
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
if not agent_client.is_available:
|
||||
raise ConfigEntryNotReady
|
||||
|
|
|
@ -125,7 +125,7 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
try:
|
||||
await measurements.update()
|
||||
except (AirlyError, ClientConnectorError) as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
|
||||
values = measurements.current["values"]
|
||||
index = measurements.current["indexes"][0]
|
||||
|
|
|
@ -227,7 +227,7 @@ async def async_setup_entry(hass, config_entry):
|
|||
try:
|
||||
return await api_coro
|
||||
except AirVisualError as err:
|
||||
raise UpdateFailed(f"Error while retrieving data: {err}")
|
||||
raise UpdateFailed(f"Error while retrieving data: {err}") from err
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
|
@ -263,7 +263,7 @@ async def async_setup_entry(hass, config_entry):
|
|||
include_trends=False,
|
||||
)
|
||||
except NodeProError as err:
|
||||
raise UpdateFailed(f"Error while retrieving data: {err}")
|
||||
raise UpdateFailed(f"Error while retrieving data: {err}") from err
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
|
|
|
@ -1542,8 +1542,10 @@ async def async_api_initialize_camera_stream(hass, config, directive, context):
|
|||
require_ssl=True,
|
||||
require_standard_port=True,
|
||||
)
|
||||
except network.NoURLAvailableError:
|
||||
raise AlexaInvalidValueError("Failed to find suitable URL to serve to Alexa")
|
||||
except network.NoURLAvailableError as err:
|
||||
raise AlexaInvalidValueError(
|
||||
"Failed to find suitable URL to serve to Alexa"
|
||||
) from err
|
||||
|
||||
payload = {
|
||||
"cameraStreams": [
|
||||
|
|
|
@ -208,7 +208,7 @@ async def _configure_almond_for_ha(
|
|||
msg = err
|
||||
_LOGGER.warning("Unable to configure Almond: %s", msg)
|
||||
await hass.auth.async_remove_refresh_token(refresh_token)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
# Clear all other refresh tokens
|
||||
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
|
||||
except WebsocketError as err:
|
||||
_LOGGER.error("Config entry failed: %s", err)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_STOP, ambient.client.websocket.disconnect()
|
||||
|
|
|
@ -375,8 +375,8 @@ class APIDomainServicesView(HomeAssistantView):
|
|||
await hass.services.async_call(
|
||||
domain, service, data, True, self.context(request)
|
||||
)
|
||||
except (vol.Invalid, ServiceNotFound):
|
||||
raise HTTPBadRequest()
|
||||
except (vol.Invalid, ServiceNotFound) as ex:
|
||||
raise HTTPBadRequest() from ex
|
||||
|
||||
return self.json(changed_states)
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class AsteriskMailbox(Mailbox):
|
|||
partial(client.mp3, msgid, sync=True)
|
||||
)
|
||||
except ServerError as err:
|
||||
raise StreamError(err)
|
||||
raise StreamError(err) from err
|
||||
|
||||
async def async_get_messages(self):
|
||||
"""Return a list of the current messages."""
|
||||
|
|
|
@ -66,7 +66,7 @@ class AtagDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
if not await self.atag.update():
|
||||
raise UpdateFailed("No data received")
|
||||
except AtagException as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
return self.atag.report
|
||||
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
outlets = dev.outlets()
|
||||
except AtenPEError as exc:
|
||||
_LOGGER.error("Failed to initialize %s:%s: %s", node, serv, str(exc))
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from exc
|
||||
|
||||
switches = []
|
||||
async for outlet in outlets:
|
||||
|
|
|
@ -171,8 +171,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
try:
|
||||
await august_gateway.async_setup(entry.data)
|
||||
return await async_setup_august(hass, entry, august_gateway)
|
||||
except asyncio.TimeoutError:
|
||||
raise ConfigEntryNotReady
|
||||
except asyncio.TimeoutError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
|
@ -339,7 +339,7 @@ class AugustData(AugustSubscriberMixin):
|
|||
device_name = self._get_device_name(device_id)
|
||||
if device_name is None:
|
||||
device_name = f"DeviceID: {device_id}"
|
||||
raise HomeAssistantError(f"{device_name}: {err}")
|
||||
raise HomeAssistantError(f"{device_name}: {err}") from err
|
||||
|
||||
return ret
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class AugustGateway:
|
|||
self._authentication = await self.authenticator.async_authenticate()
|
||||
except ClientError as 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:
|
||||
raise InvalidAuth
|
||||
|
|
|
@ -170,8 +170,8 @@ def _parse_client_id(client_id):
|
|||
try:
|
||||
# parts raises ValueError when port cannot be parsed as int
|
||||
parts.port
|
||||
except ValueError:
|
||||
raise ValueError("Client ID contains invalid port")
|
||||
except ValueError as ex:
|
||||
raise ValueError("Client ID contains invalid port") from ex
|
||||
|
||||
# Additionally, hostnames
|
||||
# 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:
|
||||
raise UpdateFailed(err)
|
||||
raise UpdateFailed(err) from err
|
||||
|
||||
async def _fetch_air_data(self, device):
|
||||
"""Fetch latest air quality data."""
|
||||
|
|
|
@ -186,8 +186,8 @@ class AxisNetworkDevice:
|
|||
password=self.config_entry.data[CONF_PASSWORD],
|
||||
)
|
||||
|
||||
except CannotConnect:
|
||||
raise ConfigEntryNotReady
|
||||
except CannotConnect as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
except Exception: # pylint: disable=broad-except
|
||||
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
|
||||
|
||||
except axis.Unauthorized:
|
||||
except axis.Unauthorized as err:
|
||||
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)
|
||||
raise CannotConnect
|
||||
raise CannotConnect from err
|
||||
|
||||
except axis.AxisException:
|
||||
except axis.AxisException as err:
|
||||
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."""
|
||||
try:
|
||||
auth.startup()
|
||||
except (LoginError, TokenRefreshFailed):
|
||||
raise InvalidAuth
|
||||
except (LoginError, TokenRefreshFailed) as err:
|
||||
raise InvalidAuth from err
|
||||
if auth.check_key_required():
|
||||
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)",
|
||||
error.args[0],
|
||||
)
|
||||
raise PlatformNotReady()
|
||||
raise PlatformNotReady() from error
|
||||
_LOGGER.error(error)
|
||||
return
|
||||
# use custom name if there's any
|
||||
|
|
|
@ -28,15 +28,15 @@ async def _validate_input(data: Dict[str, Any]) -> str:
|
|||
version = await bond.version()
|
||||
# call to non-version API is needed to validate authentication
|
||||
await bond.devices()
|
||||
except ClientConnectionError:
|
||||
raise InputValidationError("cannot_connect")
|
||||
except ClientConnectionError as error:
|
||||
raise InputValidationError("cannot_connect") from error
|
||||
except ClientResponseError as error:
|
||||
if error.status == 401:
|
||||
raise InputValidationError("invalid_auth")
|
||||
raise InputValidationError("unknown")
|
||||
except Exception:
|
||||
raise InputValidationError("invalid_auth") from error
|
||||
raise InputValidationError("unknown") from error
|
||||
except Exception as error:
|
||||
_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.
|
||||
bond_id = version.get("bondid")
|
||||
|
|
|
@ -82,8 +82,8 @@ class BroadlinkDevice:
|
|||
await self._async_handle_auth_error()
|
||||
return False
|
||||
|
||||
except (DeviceOfflineError, OSError):
|
||||
raise ConfigEntryNotReady
|
||||
except (DeviceOfflineError, OSError) as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
except BroadlinkException as err:
|
||||
_LOGGER.error(
|
||||
|
|
|
@ -175,8 +175,8 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||
|
||||
try:
|
||||
code = self._codes[device][command]
|
||||
except KeyError:
|
||||
raise KeyError("Command not found")
|
||||
except KeyError as err:
|
||||
raise KeyError("Command not found") from err
|
||||
|
||||
# For toggle commands, alternate between codes in a list.
|
||||
if isinstance(code, list):
|
||||
|
@ -187,8 +187,8 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity):
|
|||
|
||||
try:
|
||||
return data_packet(code), is_toggle_cmd
|
||||
except ValueError:
|
||||
raise ValueError("Invalid code")
|
||||
except ValueError as err:
|
||||
raise ValueError("Invalid code") from err
|
||||
|
||||
@callback
|
||||
def get_flags(self):
|
||||
|
|
|
@ -63,7 +63,7 @@ class BroadlinkUpdateManager(ABC):
|
|||
_LOGGER.warning(
|
||||
"Disconnected from the device at %s", self.device.api.host[0]
|
||||
)
|
||||
raise UpdateFailed(err)
|
||||
raise UpdateFailed(err) from err
|
||||
|
||||
else:
|
||||
if self.available is False:
|
||||
|
|
|
@ -82,5 +82,5 @@ class BrotherDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
try:
|
||||
await self.brother.async_update()
|
||||
except (ConnectionError, SnmpError, UnsupportedModel) as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
return self.brother.data
|
||||
|
|
|
@ -539,8 +539,8 @@ class CameraMjpegStream(CameraView):
|
|||
if interval < MIN_STREAM_INTERVAL:
|
||||
raise ValueError(f"Stream interval must be be > {MIN_STREAM_INTERVAL}")
|
||||
return await camera.handle_async_still_stream(request, interval)
|
||||
except ValueError:
|
||||
raise web.HTTPBadRequest()
|
||||
except ValueError as err:
|
||||
raise web.HTTPBadRequest() from err
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
|
|
|
@ -76,7 +76,7 @@ class CertExpiryDataUpdateCoordinator(DataUpdateCoordinator[datetime]):
|
|||
try:
|
||||
timestamp = await get_cert_expiry_timestamp(self.hass, self.host, self.port)
|
||||
except TemporaryFailure as err:
|
||||
raise UpdateFailed(err.args[0])
|
||||
raise UpdateFailed(err.args[0]) from err
|
||||
except ValidationFailure as err:
|
||||
self.cert_error = err
|
||||
self.is_cert_valid = False
|
||||
|
|
|
@ -28,16 +28,20 @@ async def get_cert_expiry_timestamp(hass, hostname, port):
|
|||
"""Return the certificate's expiration timestamp."""
|
||||
try:
|
||||
cert = await hass.async_add_executor_job(get_cert, hostname, port)
|
||||
except socket.gaierror:
|
||||
raise ResolveFailed(f"Cannot resolve hostname: {hostname}")
|
||||
except socket.timeout:
|
||||
raise ConnectionTimeout(f"Connection timeout with server: {hostname}:{port}")
|
||||
except ConnectionRefusedError:
|
||||
raise ConnectionRefused(f"Connection refused by server: {hostname}:{port}")
|
||||
except socket.gaierror as err:
|
||||
raise ResolveFailed(f"Cannot resolve hostname: {hostname}") from err
|
||||
except socket.timeout as err:
|
||||
raise ConnectionTimeout(
|
||||
f"Connection timeout with 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:
|
||||
raise ValidationFailure(err.verify_message)
|
||||
raise ValidationFailure(err.verify_message) from 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"])
|
||||
return dt.utc_from_timestamp(ts_seconds)
|
||||
|
|
|
@ -225,8 +225,8 @@ class CityBikesNetworks:
|
|||
result = network[ATTR_ID]
|
||||
|
||||
return result
|
||||
except CityBikesRequestError:
|
||||
raise PlatformNotReady
|
||||
except CityBikesRequestError as err:
|
||||
raise PlatformNotReady from err
|
||||
finally:
|
||||
self.networks_loading.release()
|
||||
|
||||
|
@ -251,11 +251,11 @@ class CityBikesNetwork:
|
|||
)
|
||||
self.stations = network[ATTR_NETWORK][ATTR_STATIONS_LIST]
|
||||
self.ready.set()
|
||||
except CityBikesRequestError:
|
||||
except CityBikesRequestError as err:
|
||||
if now is not None:
|
||||
self.ready.clear()
|
||||
else:
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from err
|
||||
|
||||
|
||||
class CityBikesStation(Entity):
|
||||
|
|
|
@ -59,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
await account.getAccountBearerToken()
|
||||
except client_exceptions.ClientError as exception:
|
||||
_LOGGER.error("Error connecting to Control4 account API: %s", exception)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from exception
|
||||
except BadCredentials as exception:
|
||||
_LOGGER.error(
|
||||
"Error authenticating with Control4 account API, incorrect username or password: %s",
|
||||
|
|
|
@ -45,14 +45,14 @@ async def async_setup_entry(
|
|||
try:
|
||||
return await director_update_data(hass, entry, CONTROL4_NON_DIMMER_VAR)
|
||||
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():
|
||||
"""Fetch data from Control4 director for dimmer lights."""
|
||||
try:
|
||||
return await director_update_data(hass, entry, CONTROL4_DIMMER_VAR)
|
||||
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(
|
||||
hass,
|
||||
|
|
|
@ -114,12 +114,12 @@ async def daikin_api_setup(hass, host, key, uuid, password):
|
|||
device = await Appliance.factory(
|
||||
host, session, key=key, uuid=uuid, password=password
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
except asyncio.TimeoutError as err:
|
||||
_LOGGER.debug("Connection to %s timed out", host)
|
||||
raise ConfigEntryNotReady
|
||||
except ClientConnectionError:
|
||||
raise ConfigEntryNotReady from err
|
||||
except ClientConnectionError as err:
|
||||
_LOGGER.debug("ClientConnectionError to %s", host)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.error("Unexpected error creating device %s", host)
|
||||
return None
|
||||
|
|
|
@ -98,8 +98,8 @@ class DeconzGateway:
|
|||
self.async_connection_status_callback,
|
||||
)
|
||||
|
||||
except CannotConnect:
|
||||
raise ConfigEntryNotReady
|
||||
except CannotConnect as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
LOGGER.error("Error connecting with deCONZ gateway: %s", err)
|
||||
|
@ -254,10 +254,10 @@ async def get_gateway(
|
|||
await deconz.initialize()
|
||||
return deconz
|
||||
|
||||
except errors.Unauthorized:
|
||||
except errors.Unauthorized as err:
|
||||
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])
|
||||
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)
|
||||
try:
|
||||
deluge_api.connect()
|
||||
except ConnectionRefusedError:
|
||||
except ConnectionRefusedError as err:
|
||||
_LOGGER.error("Connection to Deluge Daemon failed")
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from err
|
||||
dev = []
|
||||
for variable in config[CONF_MONITORED_VARIABLES]:
|
||||
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)
|
||||
try:
|
||||
deluge_api.connect()
|
||||
except ConnectionRefusedError:
|
||||
except ConnectionRefusedError as err:
|
||||
_LOGGER.error("Connection to Deluge Daemon failed")
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from err
|
||||
|
||||
add_entities([DelugeSwitch(deluge_api, name)])
|
||||
|
||||
|
|
|
@ -83,12 +83,14 @@ async def async_get_device_automation_platform(
|
|||
try:
|
||||
integration = await async_get_integration_with_requirements(hass, domain)
|
||||
platform = integration.get_platform(platform_name)
|
||||
except IntegrationNotFound:
|
||||
raise InvalidDeviceAutomationConfig(f"Integration '{domain}' not found")
|
||||
except ImportError:
|
||||
except IntegrationNotFound as err:
|
||||
raise InvalidDeviceAutomationConfig(
|
||||
f"Integration '{domain}' not found"
|
||||
) from err
|
||||
except ImportError as err:
|
||||
raise InvalidDeviceAutomationConfig(
|
||||
f"Integration '{domain}' does not support device automation {automation_type}s"
|
||||
)
|
||||
) from err
|
||||
|
||||
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(
|
||||
partial(HomeControl, gateway_id=gateway_id, url=mprm_url)
|
||||
)
|
||||
except ConnectionError:
|
||||
raise ConfigEntryNotReady
|
||||
except ConnectionError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
for platform in PLATFORMS:
|
||||
hass.async_create_task(
|
||||
|
|
|
@ -43,8 +43,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
)
|
||||
except AccountError:
|
||||
return False
|
||||
except SessionError:
|
||||
raise ConfigEntryNotReady
|
||||
except SessionError as error:
|
||||
raise ConfigEntryNotReady from error
|
||||
|
||||
if not entry.options:
|
||||
hass.config_entries.async_update_entry(
|
||||
|
@ -55,7 +55,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
try:
|
||||
return await hass.async_add_executor_job(dexcom.get_current_glucose_reading)
|
||||
except SessionError as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = {
|
||||
COORDINATOR: DataUpdateCoordinator(
|
||||
|
|
|
@ -59,8 +59,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
|
||||
try:
|
||||
await dtv.update()
|
||||
except DIRECTVError:
|
||||
raise ConfigEntryNotReady
|
||||
except DIRECTVError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = dtv
|
||||
|
||||
|
|
|
@ -182,8 +182,8 @@ async def async_setup_platform(
|
|||
factory = UpnpFactory(requester, disable_state_variable_validation=True)
|
||||
try:
|
||||
upnp_device = await factory.async_create_device(url)
|
||||
except (asyncio.TimeoutError, aiohttp.ClientError):
|
||||
raise PlatformNotReady()
|
||||
except (asyncio.TimeoutError, aiohttp.ClientError) as err:
|
||||
raise PlatformNotReady() from err
|
||||
|
||||
# wrap with DmrDevice
|
||||
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
|
||||
)
|
||||
return False
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
except OSError as oserr:
|
||||
_LOGGER.error("Failed to setup doorbird at %s: %s", device_ip, oserr)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from oserr
|
||||
|
||||
if not status[0]:
|
||||
_LOGGER.error(
|
||||
|
|
|
@ -40,10 +40,10 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||
info = await hass.async_add_executor_job(device.info)
|
||||
except urllib.error.HTTPError as err:
|
||||
if err.code == 401:
|
||||
raise InvalidAuth
|
||||
raise CannotConnect
|
||||
except OSError:
|
||||
raise CannotConnect
|
||||
raise InvalidAuth from err
|
||||
raise CannotConnect from err
|
||||
except OSError as err:
|
||||
raise CannotConnect from err
|
||||
|
||||
if not status[0]:
|
||||
raise CannotConnect
|
||||
|
|
|
@ -81,7 +81,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
await ebox_data.async_update()
|
||||
except PyEboxError as exp:
|
||||
_LOGGER.error("Failed login: %s", exp)
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from exp
|
||||
|
||||
sensors = []
|
||||
for variable in config[CONF_MONITORED_VARIABLES]:
|
||||
|
|
|
@ -110,7 +110,7 @@ class EbusdData:
|
|||
self.value[name] = command_result
|
||||
except RuntimeError as err:
|
||||
_LOGGER.error(err)
|
||||
raise RuntimeError(err)
|
||||
raise RuntimeError(err) from err
|
||||
|
||||
def write(self, call):
|
||||
"""Call write methon on ebusd."""
|
||||
|
|
|
@ -8,8 +8,8 @@ def ecobee_date(date_string):
|
|||
"""Validate a date_string as valid for the ecobee API."""
|
||||
try:
|
||||
datetime.strptime(date_string, "%Y-%m-%d")
|
||||
except ValueError:
|
||||
raise vol.Invalid("Date does not match ecobee date format YYYY-MM-DD")
|
||||
except ValueError as err:
|
||||
raise vol.Invalid("Date does not match ecobee date format YYYY-MM-DD") from err
|
||||
return date_string
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@ def ecobee_time(time_string):
|
|||
"""Validate a time_string as valid for the ecobee API."""
|
||||
try:
|
||||
datetime.strptime(time_string, "%H:%M:%S")
|
||||
except ValueError:
|
||||
raise vol.Invalid("Time does not match ecobee 24-hour time format HH:MM:SS")
|
||||
except ValueError as err:
|
||||
raise vol.Invalid(
|
||||
"Time does not match ecobee 24-hour time format HH:MM:SS"
|
||||
) from err
|
||||
return time_string
|
||||
|
|
|
@ -50,8 +50,8 @@ class EcobeeWeather(WeatherEntity):
|
|||
try:
|
||||
forecast = self.weather["forecasts"][index]
|
||||
return forecast[param]
|
||||
except (ValueError, IndexError, KeyError):
|
||||
raise ValueError
|
||||
except (IndexError, KeyError) as err:
|
||||
raise ValueError from err
|
||||
|
||||
@property
|
||||
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()
|
||||
|
||||
except pyeverlights.ConnectionError:
|
||||
raise PlatformNotReady
|
||||
except pyeverlights.ConnectionError as err:
|
||||
raise PlatformNotReady from err
|
||||
|
||||
else:
|
||||
lights.append(EverLightsLight(api, pyeverlights.ZONE_1, status, effects))
|
||||
|
|
|
@ -48,10 +48,10 @@ class FlickConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
try:
|
||||
with async_timeout.timeout(60):
|
||||
token = await auth.async_get_access_token()
|
||||
except asyncio.TimeoutError:
|
||||
raise CannotConnect()
|
||||
except AuthException:
|
||||
raise InvalidAuth()
|
||||
except asyncio.TimeoutError as err:
|
||||
raise CannotConnect() from err
|
||||
except AuthException as err:
|
||||
raise InvalidAuth() from err
|
||||
else:
|
||||
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(
|
||||
entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], session=session
|
||||
)
|
||||
except RequestError:
|
||||
raise ConfigEntryNotReady
|
||||
except RequestError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
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:
|
||||
_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()
|
||||
a_location_id = user_info["locations"][0]["id"]
|
||||
|
|
|
@ -46,7 +46,7 @@ class FloDeviceDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
*[self._update_device(), self._update_consumption_data()]
|
||||
)
|
||||
except (RequestError) as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
|
||||
@property
|
||||
def location_id(self) -> str:
|
||||
|
|
|
@ -67,8 +67,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
http_session=http_session,
|
||||
)
|
||||
)
|
||||
except RequestException:
|
||||
raise ConfigEntryNotReady
|
||||
except RequestException as ex:
|
||||
raise ConfigEntryNotReady from ex
|
||||
except Exception as ex: # pylint: disable=broad-except
|
||||
_LOGGER.error("Invalid credentials for flume: %s", ex)
|
||||
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)
|
||||
except RequestException:
|
||||
raise CannotConnect
|
||||
except Exception: # pylint: disable=broad-except
|
||||
raise InvalidAuth
|
||||
except RequestException as err:
|
||||
raise CannotConnect from err
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
raise InvalidAuth from err
|
||||
if not flume_devices or not flume_devices.device_list:
|
||||
raise CannotConnect
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ def async_get_api_category(sensor_type):
|
|||
if sensor[0] == sensor_type
|
||||
)
|
||||
)
|
||||
except StopIteration:
|
||||
raise ValueError(f"Can't find category sensor type: {sensor_type}")
|
||||
except StopIteration as err:
|
||||
raise ValueError(f"Can't find category sensor type: {sensor_type}") from err
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
|
|
|
@ -82,9 +82,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
asyncio.TimeoutError,
|
||||
FoobotClient.TooManyRequests,
|
||||
FoobotClient.InternalError,
|
||||
):
|
||||
) as err:
|
||||
_LOGGER.exception("Failed to connect to foobot servers")
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from err
|
||||
except FoobotClient.ClientError:
|
||||
_LOGGER.error("Failed to fetch data from foobot servers")
|
||||
return
|
||||
|
|
|
@ -49,7 +49,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
_LOGGER.error(
|
||||
"Connection error occurred during Garmin Connect login request: %s", err
|
||||
)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unknown error occurred during Garmin Connect login request")
|
||||
return False
|
||||
|
|
|
@ -69,7 +69,7 @@ class GiosDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
ClientConnectorError,
|
||||
InvalidSensorsData,
|
||||
) as error:
|
||||
raise UpdateFailed(error)
|
||||
raise UpdateFailed(error) from error
|
||||
if not self.gios.data:
|
||||
raise UpdateFailed("Invalid sensors data")
|
||||
return self.gios.data
|
||||
|
|
|
@ -121,9 +121,9 @@ class GlancesData:
|
|||
self.available = True
|
||||
_LOGGER.debug("Successfully connected to Glances")
|
||||
|
||||
except exceptions.GlancesApiConnectionError:
|
||||
except exceptions.GlancesApiConnectionError as err:
|
||||
_LOGGER.debug("Can not connect to Glances")
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
self.add_options()
|
||||
self.set_scan_interval(self.config_entry.options[CONF_SCAN_INTERVAL])
|
||||
|
|
|
@ -52,8 +52,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||
try:
|
||||
api = get_api(hass, data)
|
||||
await api.get_data()
|
||||
except glances_api.exceptions.GlancesApiConnectionError:
|
||||
raise CannotConnect
|
||||
except glances_api.exceptions.GlancesApiConnectionError as err:
|
||||
raise CannotConnect from err
|
||||
|
||||
|
||||
class GlancesFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
|
|
@ -69,7 +69,9 @@ def get_data_update_coordinator(
|
|||
async with async_timeout.timeout(3):
|
||||
return await hass.async_add_executor_job(api.info)
|
||||
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(
|
||||
hass,
|
||||
|
|
|
@ -28,8 +28,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||
await AsyncGriddy(
|
||||
client_session, settlement_point=data[CONF_LOADZONE]
|
||||
).async_getnow()
|
||||
except (asyncio.TimeoutError, ClientError):
|
||||
raise CannotConnect
|
||||
except (asyncio.TimeoutError, ClientError) as err:
|
||||
raise CannotConnect from err
|
||||
|
||||
# Return info that you want to store in the config entry.
|
||||
return {"title": f"Load Zone {data[CONF_LOADZONE]}"}
|
||||
|
|
|
@ -45,5 +45,5 @@ class GuardianDataUpdateCoordinator(DataUpdateCoordinator[dict]):
|
|||
try:
|
||||
resp = await self._api_coro()
|
||||
except GuardianError as err:
|
||||
raise UpdateFailed(err)
|
||||
raise UpdateFailed(err) from err
|
||||
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
|
||||
)
|
||||
connected_ok = await device.connect()
|
||||
except (asyncio.TimeoutError, ValueError, AttributeError):
|
||||
raise ConfigEntryNotReady
|
||||
except (asyncio.TimeoutError, ValueError, AttributeError) as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
if not connected_ok:
|
||||
raise ConfigEntryNotReady
|
||||
|
|
|
@ -111,7 +111,7 @@ class HassIOPasswordReset(HassIOBaseAuth):
|
|||
await provider.async_change_password(
|
||||
data[ATTR_USERNAME], data[ATTR_PASSWORD]
|
||||
)
|
||||
except auth_ha.InvalidUser:
|
||||
raise HTTPNotFound()
|
||||
except auth_ha.InvalidUser as err:
|
||||
raise HTTPNotFound() from err
|
||||
|
||||
return web.Response(status=HTTP_OK)
|
||||
|
|
|
@ -75,7 +75,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||
except HeosError as error:
|
||||
await controller.disconnect()
|
||||
_LOGGER.debug("Unable to connect to controller %s: %s", host, error)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from error
|
||||
|
||||
# Disconnect when shutting down
|
||||
async def disconnect_controller(event):
|
||||
|
@ -99,7 +99,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||
except HeosError as error:
|
||||
await controller.disconnect()
|
||||
_LOGGER.debug("Unable to retrieve players and sources: %s", error)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from error
|
||||
|
||||
controller_manager = ControllerManager(hass, controller)
|
||||
await controller_manager.connect_listeners()
|
||||
|
|
|
@ -22,8 +22,8 @@ def coerce_ip(value):
|
|||
raise vol.Invalid("Must define an IP address")
|
||||
try:
|
||||
ipaddress.IPv4Network(value)
|
||||
except ValueError:
|
||||
raise vol.Invalid("Not a valid IP address")
|
||||
except ValueError as err:
|
||||
raise vol.Invalid("Not a valid IP address") from err
|
||||
return value
|
||||
|
||||
|
||||
|
|
|
@ -49,8 +49,8 @@ async def validate_input(hass: HomeAssistant, user_input):
|
|||
|
||||
try:
|
||||
client = await connect_client(hass, user_input)
|
||||
except asyncio.TimeoutError:
|
||||
raise CannotConnect
|
||||
except asyncio.TimeoutError as err:
|
||||
raise CannotConnect from err
|
||||
try:
|
||||
|
||||
def disconnect_callback():
|
||||
|
@ -62,7 +62,7 @@ async def validate_input(hass: HomeAssistant, user_input):
|
|||
except CannotConnect:
|
||||
client.disconnect_callback = None
|
||||
client.stop()
|
||||
raise CannotConnect
|
||||
raise
|
||||
else:
|
||||
client.disconnect_callback = None
|
||||
client.stop()
|
||||
|
|
|
@ -40,8 +40,8 @@ class TimePattern:
|
|||
|
||||
if not (0 <= number <= self.maximum):
|
||||
raise vol.Invalid(f"must be a value between 0 and {self.maximum}")
|
||||
except ValueError:
|
||||
raise vol.Invalid("invalid time_pattern value")
|
||||
except ValueError as err:
|
||||
raise vol.Invalid("invalid time_pattern value") from err
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ class HomematicipHAP:
|
|||
self.config_entry.data.get(HMIPC_AUTHTOKEN),
|
||||
self.config_entry.data.get(HMIPC_NAME),
|
||||
)
|
||||
except HmipcConnectionError:
|
||||
raise ConfigEntryNotReady
|
||||
except HmipcConnectionError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.error("Error connecting with HomematicIP Cloud: %s", err)
|
||||
return False
|
||||
|
@ -247,8 +247,8 @@ class HomematicipHAP:
|
|||
try:
|
||||
await home.init(hapid)
|
||||
await home.get_current_state()
|
||||
except HmipConnectionError:
|
||||
raise HmipcConnectionError
|
||||
except HmipConnectionError as err:
|
||||
raise HmipcConnectionError from err
|
||||
home.on_update(self.async_update)
|
||||
home.on_create(self.async_create_entity)
|
||||
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:
|
||||
# occurs if horizon box is offline
|
||||
_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)
|
||||
|
||||
|
|
|
@ -191,4 +191,4 @@ class HpIloData:
|
|||
hpilo.IloCommunicationError,
|
||||
hpilo.IloLoginFailed,
|
||||
) 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(",")))
|
||||
try:
|
||||
forwarded_for = [ip_address(addr.strip()) for addr in forwarded_for_split]
|
||||
except ValueError:
|
||||
except ValueError as err:
|
||||
_LOGGER.error(
|
||||
"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
|
||||
forwarded_for_index = 0
|
||||
|
|
|
@ -52,7 +52,7 @@ class HomeAssistantView:
|
|||
msg = json.dumps(result, cls=JSONEncoder, allow_nan=False).encode("UTF-8")
|
||||
except (ValueError, TypeError) as err:
|
||||
_LOGGER.error("Unable to serialize to JSON: %s\n%s", err, result)
|
||||
raise HTTPInternalServerError
|
||||
raise HTTPInternalServerError from err
|
||||
response = web.Response(
|
||||
body=msg,
|
||||
content_type=CONTENT_TYPE_JSON,
|
||||
|
@ -127,12 +127,12 @@ def request_handler_factory(view: HomeAssistantView, handler: Callable) -> Calla
|
|||
|
||||
if asyncio.iscoroutine(result):
|
||||
result = await result
|
||||
except vol.Invalid:
|
||||
raise HTTPBadRequest()
|
||||
except exceptions.ServiceNotFound:
|
||||
raise HTTPInternalServerError()
|
||||
except exceptions.Unauthorized:
|
||||
raise HTTPUnauthorized()
|
||||
except vol.Invalid as err:
|
||||
raise HTTPBadRequest() from err
|
||||
except exceptions.ServiceNotFound as err:
|
||||
raise HTTPInternalServerError() from err
|
||||
except exceptions.Unauthorized as err:
|
||||
raise HTTPUnauthorized() from err
|
||||
|
||||
if isinstance(result, web.StreamResponse):
|
||||
# The method handler returned a ready-made Response, how nice of it
|
||||
|
|
|
@ -94,9 +94,9 @@ class HueBridge:
|
|||
create_config_flow(hass, host)
|
||||
return False
|
||||
|
||||
except CannotConnect:
|
||||
except CannotConnect as err:
|
||||
LOGGER.error("Error connecting to the Hue bridge at %s", host)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
except Exception: # pylint: disable=broad-except
|
||||
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)
|
||||
await bridge.initialize()
|
||||
|
||||
except (aiohue.LinkButtonNotPressed, aiohue.Unauthorized):
|
||||
raise AuthenticationRequired
|
||||
except (aiohue.LinkButtonNotPressed, aiohue.Unauthorized) as err:
|
||||
raise AuthenticationRequired from err
|
||||
except (
|
||||
asyncio.TimeoutError,
|
||||
client_exceptions.ClientOSError,
|
||||
client_exceptions.ServerDisconnectedError,
|
||||
client_exceptions.ContentTypeError,
|
||||
):
|
||||
raise CannotConnect
|
||||
except aiohue.AiohueException:
|
||||
) as err:
|
||||
raise CannotConnect from err
|
||||
except aiohue.AiohueException as err:
|
||||
LOGGER.exception("Unknown Hue linking error occurred")
|
||||
raise AuthenticationRequired
|
||||
raise AuthenticationRequired from err
|
||||
|
||||
|
||||
async def _update_listener(hass, entry):
|
||||
|
|
|
@ -159,11 +159,11 @@ async def async_safe_fetch(bridge, fetch_method):
|
|||
try:
|
||||
with async_timeout.timeout(4):
|
||||
return await bridge.async_request_call(fetch_method)
|
||||
except aiohue.Unauthorized:
|
||||
except aiohue.Unauthorized as err:
|
||||
await bridge.handle_unauthorized_error()
|
||||
raise UpdateFailed("Unauthorized")
|
||||
raise UpdateFailed("Unauthorized") from err
|
||||
except (aiohue.AiohueException,) as err:
|
||||
raise UpdateFailed(f"Hue error: {err}")
|
||||
raise UpdateFailed(f"Hue error: {err}") from err
|
||||
|
||||
|
||||
@callback
|
||||
|
|
|
@ -61,11 +61,11 @@ class SensorManager:
|
|||
return await self.bridge.async_request_call(
|
||||
self.bridge.api.sensors.update
|
||||
)
|
||||
except Unauthorized:
|
||||
except Unauthorized as err:
|
||||
await self.bridge.handle_unauthorized_error()
|
||||
raise UpdateFailed("Unauthorized")
|
||||
raise UpdateFailed("Unauthorized") from 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):
|
||||
"""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(
|
||||
(await shades.get_resources())[SHADE_DATA]
|
||||
)
|
||||
except HUB_EXCEPTIONS:
|
||||
except HUB_EXCEPTIONS as err:
|
||||
_LOGGER.error("Connection error to PowerView hub: %s", hub_address)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
if not device_info:
|
||||
_LOGGER.error("Unable to initialize PowerView hub: %s", hub_address)
|
||||
|
|
|
@ -33,8 +33,8 @@ async def validate_input(hass: core.HomeAssistant, data):
|
|||
try:
|
||||
async with async_timeout.timeout(10):
|
||||
device_info = await async_get_device_info(pv_request)
|
||||
except HUB_EXCEPTIONS:
|
||||
raise CannotConnect
|
||||
except HUB_EXCEPTIONS as err:
|
||||
raise CannotConnect from err
|
||||
if not device_info:
|
||||
raise CannotConnect
|
||||
|
||||
|
|
|
@ -41,16 +41,16 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
try:
|
||||
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
||||
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")
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from err
|
||||
|
||||
async def async_update_data():
|
||||
try:
|
||||
with async_timeout.timeout(PLATFORM_TIMEOUT):
|
||||
return await api.get_data()
|
||||
except (IamMeterError, asyncio.TimeoutError):
|
||||
raise UpdateFailed
|
||||
except (IamMeterError, asyncio.TimeoutError) as err:
|
||||
raise UpdateFailed from err
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
|
|
|
@ -96,7 +96,7 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> None
|
|||
aiohttp.client_exceptions.ClientConnectorError,
|
||||
) as 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 = list(systems.values())
|
||||
|
|
|
@ -119,9 +119,12 @@ class IcloudAccount:
|
|||
api_devices = self.api.devices
|
||||
# Gets device owners infos
|
||||
user_info = api_devices.response["userInfo"]
|
||||
except (PyiCloudServiceNotActivatedException, PyiCloudNoDevicesException):
|
||||
except (
|
||||
PyiCloudServiceNotActivatedException,
|
||||
PyiCloudNoDevicesException,
|
||||
) as err:
|
||||
_LOGGER.error("No iCloud device found")
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
self._owner_fullname = f"{user_info['firstName']} {user_info['lastName']}"
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ class ImageStorageCollection(collection.StorageCollection):
|
|||
# Verify we can read the image
|
||||
try:
|
||||
image = Image.open(uploaded_file.file)
|
||||
except UnidentifiedImageError:
|
||||
raise vol.Invalid("Unable to identify image file")
|
||||
except UnidentifiedImageError as err:
|
||||
raise vol.Invalid("Unable to identify image file") from err
|
||||
|
||||
# Reset content
|
||||
uploaded_file.file.seek(0)
|
||||
|
@ -170,8 +170,8 @@ class ImageServeView(HomeAssistantView):
|
|||
parts = image_size.split("x", 1)
|
||||
width = int(parts[0])
|
||||
height = int(parts[1])
|
||||
except (ValueError, IndexError):
|
||||
raise web.HTTPBadRequest
|
||||
except (ValueError, IndexError) as err:
|
||||
raise web.HTTPBadRequest from err
|
||||
|
||||
if not width or width != height or width not in VALID_SIZES:
|
||||
raise web.HTTPBadRequest
|
||||
|
|
|
@ -324,22 +324,22 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||
try:
|
||||
write_api.write(bucket=bucket, record=json)
|
||||
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
||||
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||
except ApiException as exc:
|
||||
if exc.status == CODE_INVALID_INPUTS:
|
||||
raise ValueError(WRITE_ERROR % (json, exc))
|
||||
raise ConnectionError(CLIENT_ERROR_V2 % exc)
|
||||
raise ValueError(WRITE_ERROR % (json, exc)) from exc
|
||||
raise ConnectionError(CLIENT_ERROR_V2 % exc) from exc
|
||||
|
||||
def query_v2(query, _=None):
|
||||
"""Query V2 influx."""
|
||||
try:
|
||||
return query_api.query(query)
|
||||
except (urllib3.exceptions.HTTPError, OSError) as exc:
|
||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
||||
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||
except ApiException as exc:
|
||||
if exc.status == CODE_INVALID_INPUTS:
|
||||
raise ValueError(QUERY_ERROR % (query, exc))
|
||||
raise ConnectionError(CLIENT_ERROR_V2 % exc)
|
||||
raise ValueError(QUERY_ERROR % (query, exc)) from exc
|
||||
raise ConnectionError(CLIENT_ERROR_V2 % exc) from exc
|
||||
|
||||
def close_v2():
|
||||
"""Close V2 influx client."""
|
||||
|
@ -399,11 +399,11 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||
exceptions.InfluxDBServerError,
|
||||
OSError,
|
||||
) as exc:
|
||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
||||
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||
except exceptions.InfluxDBClientError as exc:
|
||||
if exc.code == CODE_INVALID_INPUTS:
|
||||
raise ValueError(WRITE_ERROR % (json, exc))
|
||||
raise ConnectionError(CLIENT_ERROR_V1 % exc)
|
||||
raise ValueError(WRITE_ERROR % (json, exc)) from exc
|
||||
raise ConnectionError(CLIENT_ERROR_V1 % exc) from exc
|
||||
|
||||
def query_v1(query, database=None):
|
||||
"""Query V1 influx."""
|
||||
|
@ -414,11 +414,11 @@ def get_influx_connection(conf, test_write=False, test_read=False):
|
|||
exceptions.InfluxDBServerError,
|
||||
OSError,
|
||||
) as exc:
|
||||
raise ConnectionError(CONNECTION_ERROR % exc)
|
||||
raise ConnectionError(CONNECTION_ERROR % exc) from exc
|
||||
except exceptions.InfluxDBClientError as exc:
|
||||
if exc.code == CODE_INVALID_INPUTS:
|
||||
raise ValueError(QUERY_ERROR % (query, exc))
|
||||
raise ConnectionError(CLIENT_ERROR_V1 % exc)
|
||||
raise ValueError(QUERY_ERROR % (query, exc)) from exc
|
||||
raise ConnectionError(CLIENT_ERROR_V1 % exc) from exc
|
||||
|
||||
def close_v1():
|
||||
"""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)
|
||||
except ConnectionError as exc:
|
||||
_LOGGER.error(exc)
|
||||
raise PlatformNotReady()
|
||||
raise PlatformNotReady() from exc
|
||||
|
||||
entities = []
|
||||
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")
|
||||
try:
|
||||
entry = unhexlify(entry)
|
||||
except HexError:
|
||||
raise ValueError("Not a valid hex code")
|
||||
except HexError as err:
|
||||
raise ValueError("Not a valid hex code") from err
|
||||
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]))
|
||||
cat = normalize_byte_entry_to_int(new_override[CONF_CAT])
|
||||
subcat = normalize_byte_entry_to_int(new_override[CONF_SUBCAT])
|
||||
except ValueError:
|
||||
raise ValueError("Incorrect values")
|
||||
except ValueError as err:
|
||||
raise ValueError("Incorrect values") from err
|
||||
|
||||
overrides = config_data.get(CONF_OVERRIDE, [])
|
||||
curr_override = {}
|
||||
|
|
|
@ -107,9 +107,9 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||
except IHAuthenticationError:
|
||||
_LOGGER.error("Invalid username or password")
|
||||
return
|
||||
except IHConnectionError:
|
||||
except IHConnectionError as ex:
|
||||
_LOGGER.error("Error connecting to the %s server", device_type)
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from ex
|
||||
|
||||
ih_devices = controller.get_devices()
|
||||
if ih_devices:
|
||||
|
@ -199,7 +199,7 @@ class IntesisAC(ClimateEntity):
|
|||
await self._controller.connect()
|
||||
except IHConnectionError as ex:
|
||||
_LOGGER.error("Exception connecting to IntesisHome: %s", ex)
|
||||
raise PlatformNotReady
|
||||
raise PlatformNotReady from ex
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
|
|
@ -121,7 +121,7 @@ class IPPDataUpdateCoordinator(DataUpdateCoordinator[IPPPrinter]):
|
|||
try:
|
||||
return await self.ipp.printer()
|
||||
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):
|
||||
|
|
|
@ -174,8 +174,8 @@ class IslamicPrayerClient:
|
|||
|
||||
try:
|
||||
await self.hass.async_add_executor_job(self.get_new_prayer_times)
|
||||
except (exceptions.InvalidResponseError, ConnError):
|
||||
raise ConfigEntryNotReady
|
||||
except (exceptions.InvalidResponseError, ConnError) as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
await self.async_update()
|
||||
self.config_entry.add_update_listener(self.async_options_updated)
|
||||
|
|
|
@ -98,7 +98,7 @@ def _fetch_isy_configuration(
|
|||
webroot=webroot,
|
||||
)
|
||||
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())
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
return False
|
||||
except aiohttp.ClientError as error:
|
||||
_LOGGER.error("Could not reach the JuiceNet API %s", error)
|
||||
raise ConfigEntryNotReady
|
||||
raise ConfigEntryNotReady from error
|
||||
|
||||
if not juicenet.devices:
|
||||
_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()
|
||||
except TokenError as error:
|
||||
_LOGGER.error("Token Error %s", error)
|
||||
raise InvalidAuth
|
||||
raise InvalidAuth from error
|
||||
except aiohttp.ClientError as 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 {"title": "JuiceNet"}
|
||||
|
|
|
@ -186,8 +186,8 @@ class KonnectedFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
try:
|
||||
status = await get_status(self.hass, host, port)
|
||||
self.data[CONF_ID] = status.get("chipId", status["mac"].replace(":", ""))
|
||||
except (CannotConnect, KeyError):
|
||||
raise CannotConnect
|
||||
except (CannotConnect, KeyError) as err:
|
||||
raise CannotConnect from err
|
||||
else:
|
||||
self.data[CONF_MODEL] = status.get("model", KONN_MODEL)
|
||||
self.data[CONF_ACCESS_TOKEN] = "".join(
|
||||
|
|
|
@ -390,4 +390,4 @@ async def get_status(hass, host, port):
|
|||
|
||||
except client.ClientError as 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()
|
||||
hass.data[DOMAIN][DATA_LUFTDATEN_CLIENT][config_entry.entry_id] = luftdaten
|
||||
except LuftdatenError:
|
||||
raise ConfigEntryNotReady
|
||||
except LuftdatenError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(config_entry, "sensor")
|
||||
|
|
|
@ -103,9 +103,9 @@ class MediaExtractor:
|
|||
|
||||
try:
|
||||
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
|
||||
raise MEDownloadException()
|
||||
raise MEDownloadException() from err
|
||||
|
||||
if "entries" in all_media:
|
||||
_LOGGER.warning("Playlists are not supported, looking for the first video")
|
||||
|
@ -123,9 +123,9 @@ class MediaExtractor:
|
|||
try:
|
||||
ydl.params["format"] = query
|
||||
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)
|
||||
raise MEQueryException()
|
||||
raise MEQueryException() from err
|
||||
|
||||
return requested_stream["url"]
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ class MetDataUpdateCoordinator(DataUpdateCoordinator):
|
|||
try:
|
||||
return await self.weather.fetch_data()
|
||||
except Exception as err:
|
||||
raise UpdateFailed(f"Update failed: {err}")
|
||||
raise UpdateFailed(f"Update failed: {err}") from err
|
||||
|
||||
def track_home(self):
|
||||
"""Start tracking changes to HA home setting."""
|
||||
|
|
|
@ -253,7 +253,7 @@ class MikrotikData:
|
|||
socket.timeout,
|
||||
) as 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:
|
||||
_LOGGER.warning(
|
||||
"Mikrotik %s failed to retrieve data. cmd=[%s] Error: %s",
|
||||
|
@ -367,8 +367,8 @@ class MikrotikHub:
|
|||
api = await self.hass.async_add_executor_job(
|
||||
get_api, self.hass, self.config_entry.data
|
||||
)
|
||||
except CannotConnect:
|
||||
raise ConfigEntryNotReady
|
||||
except CannotConnect as api_error:
|
||||
raise ConfigEntryNotReady from api_error
|
||||
except LoginError:
|
||||
return False
|
||||
|
||||
|
@ -415,5 +415,5 @@ def get_api(hass, entry):
|
|||
) as api_error:
|
||||
_LOGGER.error("Mikrotik %s error: %s", entry[CONF_HOST], api_error)
|
||||
if "invalid user name or password" in str(api_error):
|
||||
raise LoginError
|
||||
raise CannotConnect
|
||||
raise LoginError from api_error
|
||||
raise CannotConnect from api_error
|
||||
|
|
|
@ -219,7 +219,7 @@ async def webhook_call_service(hass, config_entry, data):
|
|||
config_entry.data[ATTR_DEVICE_NAME],
|
||||
ex,
|
||||
)
|
||||
raise HTTPBadRequest()
|
||||
raise HTTPBadRequest() from ex
|
||||
|
||||
return empty_okay_response()
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue