Simplify Reolink exception handling (#141427)

This commit is contained in:
Robert Resch 2025-03-26 08:53:46 +01:00 committed by GitHub
parent dd914deb47
commit 18dfd3db88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 34 additions and 77 deletions

View File

@ -108,6 +108,20 @@ def check_translation_key(err: ReolinkError) -> str | None:
return err.translation_key return err.translation_key
_EXCEPTION_TO_TRANSLATION_KEY = {
ApiError: "api_error",
InvalidContentTypeError: "invalid_content_type",
CredentialsInvalidError: "invalid_credentials",
LoginError: "login_error",
NoDataError: "no_data",
UnexpectedDataError: "unexpected_data",
NotSupportedError: "not_supported",
SubscriptionError: "subscription_error",
ReolinkConnectionError: "connection_error",
ReolinkTimeoutError: "timeout",
}
# Decorators # Decorators
def raise_translated_error[**P, R]( def raise_translated_error[**P, R](
func: Callable[P, Awaitable[R]], func: Callable[P, Awaitable[R]],
@ -124,70 +138,11 @@ def raise_translated_error[**P, R](
translation_key=check_translation_key(err) or "invalid_parameter", translation_key=check_translation_key(err) or "invalid_parameter",
translation_placeholders={"err": str(err)}, translation_placeholders={"err": str(err)},
) from err ) from err
except ApiError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "api_error",
translation_placeholders={"err": str(err)},
) from err
except InvalidContentTypeError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "invalid_content_type",
translation_placeholders={"err": str(err)},
) from err
except CredentialsInvalidError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "invalid_credentials",
translation_placeholders={"err": str(err)},
) from err
except LoginError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "login_error",
translation_placeholders={"err": str(err)},
) from err
except NoDataError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "no_data",
translation_placeholders={"err": str(err)},
) from err
except UnexpectedDataError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "unexpected_data",
translation_placeholders={"err": str(err)},
) from err
except NotSupportedError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "not_supported",
translation_placeholders={"err": str(err)},
) from err
except SubscriptionError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "subscription_error",
translation_placeholders={"err": str(err)},
) from err
except ReolinkConnectionError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "connection_error",
translation_placeholders={"err": str(err)},
) from err
except ReolinkTimeoutError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "timeout",
translation_placeholders={"err": str(err)},
) from err
except ReolinkError as err: except ReolinkError as err:
raise HomeAssistantError( raise HomeAssistantError(
translation_domain=DOMAIN, translation_domain=DOMAIN,
translation_key=check_translation_key(err) or "unexpected", translation_key=check_translation_key(err)
or _EXCEPTION_TO_TRANSLATION_KEY.get(type(err), "unexpected"),
translation_placeholders={"err": str(err)}, translation_placeholders={"err": str(err)},
) from err ) from err

View File

@ -38,59 +38,59 @@ from tests.common import MockConfigEntry
[ [
( (
ApiError("Test error"), ApiError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="api_error"),
), ),
( (
ApiError("Test error", translation_key="firmware_rate_limit"), ApiError("Test error", translation_key="firmware_rate_limit"),
HomeAssistantError, HomeAssistantError(translation_key="firmware_rate_limit"),
), ),
( (
ApiError("Test error", translation_key="not_in_strings.json"), ApiError("Test error", translation_key="not_in_strings.json"),
HomeAssistantError, HomeAssistantError(translation_key="api_error"),
), ),
( (
CredentialsInvalidError("Test error"), CredentialsInvalidError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="invalid_credentials"),
), ),
( (
InvalidContentTypeError("Test error"), InvalidContentTypeError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="invalid_content_type"),
), ),
( (
InvalidParameterError("Test error"), InvalidParameterError("Test error"),
ServiceValidationError, ServiceValidationError(translation_key="invalid_parameter"),
), ),
( (
LoginError("Test error"), LoginError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="login_error"),
), ),
( (
NoDataError("Test error"), NoDataError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="no_data"),
), ),
( (
NotSupportedError("Test error"), NotSupportedError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="not_supported"),
), ),
( (
ReolinkConnectionError("Test error"), ReolinkConnectionError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="connection_error"),
), ),
( (
ReolinkError("Test error"), ReolinkError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="unexpected"),
), ),
( (
ReolinkTimeoutError("Test error"), ReolinkTimeoutError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="timeout"),
), ),
( (
SubscriptionError("Test error"), SubscriptionError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="subscription_error"),
), ),
( (
UnexpectedDataError("Test error"), UnexpectedDataError("Test error"),
HomeAssistantError, HomeAssistantError(translation_key="unexpected_data"),
), ),
], ],
) )
@ -99,7 +99,7 @@ async def test_try_function(
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
reolink_connect: MagicMock, reolink_connect: MagicMock,
side_effect: ReolinkError, side_effect: ReolinkError,
expected: Exception, expected: HomeAssistantError,
) -> None: ) -> None:
"""Test try_function error translations using number entity.""" """Test try_function error translations using number entity."""
reolink_connect.volume.return_value = 80 reolink_connect.volume.return_value = 80
@ -112,7 +112,7 @@ async def test_try_function(
entity_id = f"{Platform.NUMBER}.{TEST_NVR_NAME}_volume" entity_id = f"{Platform.NUMBER}.{TEST_NVR_NAME}_volume"
reolink_connect.set_volume.side_effect = side_effect reolink_connect.set_volume.side_effect = side_effect
with pytest.raises(expected): with pytest.raises(expected.__class__) as err:
await hass.services.async_call( await hass.services.async_call(
NUMBER_DOMAIN, NUMBER_DOMAIN,
SERVICE_SET_VALUE, SERVICE_SET_VALUE,
@ -120,4 +120,6 @@ async def test_try_function(
blocking=True, blocking=True,
) )
assert err.value.translation_key == expected.translation_key
reolink_connect.set_volume.reset_mock(side_effect=True) reolink_connect.set_volume.reset_mock(side_effect=True)