diff --git a/homeassistant/components/playstation_network/coordinator.py b/homeassistant/components/playstation_network/coordinator.py index 977632de23b..94b178dc0c3 100644 --- a/homeassistant/components/playstation_network/coordinator.py +++ b/homeassistant/components/playstation_network/coordinator.py @@ -5,6 +5,7 @@ from __future__ import annotations from abc import abstractmethod from dataclasses import dataclass from datetime import timedelta +import json import logging from typing import TYPE_CHECKING, Any @@ -21,12 +22,14 @@ from psnawp_api.models.group.group_datatypes import GroupDetails from psnawp_api.models.trophies import TrophyTitle from homeassistant.config_entries import ConfigEntry, ConfigSubentry +from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import ( ConfigEntryAuthFailed, ConfigEntryError, ConfigEntryNotReady, ) +from homeassistant.helpers import issue_registry as ir from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN @@ -143,13 +146,34 @@ class PlaystationNetworkGroupsUpdateCoordinator( async def update_data(self) -> dict[str, GroupDetails]: """Update groups data.""" - return await self.hass.async_add_executor_job( - lambda: { - group_info.group_id: group_info.get_group_information() - for group_info in self.psn.client.get_groups() - if not group_info.group_id.startswith("~") - } - ) + try: + return await self.hass.async_add_executor_job( + lambda: { + group_info.group_id: group_info.get_group_information() + for group_info in self.psn.client.get_groups() + if not group_info.group_id.startswith("~") + } + ) + except PSNAWPForbiddenError as e: + try: + error = json.loads(e.args[0]) + except json.JSONDecodeError as err: + raise PSNAWPServerError from err + ir.async_create_issue( + self.hass, + DOMAIN, + f"group_chat_forbidden_{self.config_entry.entry_id}", + is_fixable=False, + issue_domain=DOMAIN, + severity=ir.IssueSeverity.ERROR, + translation_key="group_chat_forbidden", + translation_placeholders={ + CONF_NAME: self.config_entry.title, + "error_message": error["error"]["message"], + }, + ) + await self.async_shutdown() + return {} class PlaystationNetworkFriendDataCoordinator( diff --git a/homeassistant/components/playstation_network/strings.json b/homeassistant/components/playstation_network/strings.json index 15b83b7cd0d..b774d3a1b67 100644 --- a/homeassistant/components/playstation_network/strings.json +++ b/homeassistant/components/playstation_network/strings.json @@ -164,5 +164,11 @@ "name": "Direct message" } } + }, + "issues": { + "group_chat_forbidden": { + "title": "Failed to retrieve group chats for {name}", + "description": "The PlayStation Network integration was unable to retrieve group chats for **{name}**.\n\nThis is likely due to insufficient permissions (Error: `{error_message}`).\n\nTo resolve this issue, please ensure the account's chat and messaging feature is not restricted by parental controls or other privacy settings.\n\nIf the restriction is intentional, you can safely ignore this message." + } } } diff --git a/tests/components/playstation_network/test_notify.py b/tests/components/playstation_network/test_notify.py index f81e03dfcc4..4d5ad7df7d4 100644 --- a/tests/components/playstation_network/test_notify.py +++ b/tests/components/playstation_network/test_notify.py @@ -18,11 +18,12 @@ from homeassistant.components.notify import ( DOMAIN as NOTIFY_DOMAIN, SERVICE_SEND_MESSAGE, ) +from homeassistant.components.playstation_network.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import entity_registry as er +from homeassistant.helpers import entity_registry as er, issue_registry as ir from tests.common import MockConfigEntry, snapshot_platform @@ -130,3 +131,29 @@ async def test_send_message_exceptions( ) mock_psnawpapi.group.return_value.send_message.assert_called_once_with("henlo fren") + + +async def test_notify_skip_forbidden( + hass: HomeAssistant, + config_entry: MockConfigEntry, + mock_psnawpapi: MagicMock, + issue_registry: ir.IssueRegistry, +) -> None: + """Test we skip creation of notifiers if forbidden by parental controls.""" + + mock_psnawpapi.me.return_value.get_groups.side_effect = PSNAWPForbiddenError( + """{"error": {"message": "Not permitted by parental control"}}""" + ) + + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED + + state = hass.states.get("notify.testuser_group_publicuniversalfriend") + assert state is None + + assert issue_registry.async_get_issue( + domain=DOMAIN, issue_id=f"group_chat_forbidden_{config_entry.entry_id}" + )