From f39f087b10f0e43a2b86f985b861f74733fa85cf Mon Sep 17 00:00:00 2001 From: jjlawren Date: Tue, 13 Jul 2021 13:22:31 -0500 Subject: [PATCH] More graceful exception handling in Plex library sensors (#52969) --- homeassistant/components/plex/sensor.py | 8 +++++++ tests/components/plex/test_sensor.py | 31 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/homeassistant/components/plex/sensor.py b/homeassistant/components/plex/sensor.py index 2bfd0d0d926..8ca72e8fb83 100644 --- a/homeassistant/components/plex/sensor.py +++ b/homeassistant/components/plex/sensor.py @@ -2,6 +2,7 @@ import logging from plexapi.exceptions import NotFound +import requests.exceptions from homeassistant.components.sensor import SensorEntity from homeassistant.helpers.debounce import Debouncer @@ -148,6 +149,13 @@ class PlexLibrarySectionSensor(SensorEntity): self._attr_available = True except NotFound: self._attr_available = False + except requests.exceptions.RequestException as err: + _LOGGER.error( + "Could not update library sensor for '%s': %s", + self.library_section.title, + err, + ) + self._attr_available = False self.async_write_ha_state() def _update_state_and_attrs(self): diff --git a/tests/components/plex/test_sensor.py b/tests/components/plex/test_sensor.py index 5fa50892f32..39a2901e72d 100644 --- a/tests/components/plex/test_sensor.py +++ b/tests/components/plex/test_sensor.py @@ -1,6 +1,8 @@ """Tests for Plex sensors.""" from datetime import timedelta +import requests.exceptions + from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY from homeassistant.const import STATE_UNAVAILABLE from homeassistant.helpers import entity_registry as er @@ -15,6 +17,7 @@ LIBRARY_UPDATE_PAYLOAD = {"StatusNotification": [{"title": "Library scan complet async def test_library_sensor_values( hass, + caplog, setup_plex_server, mock_websocket, requests_mock, @@ -63,6 +66,34 @@ async def test_library_sensor_values( assert library_tv_sensor.attributes["seasons"] == 1 assert library_tv_sensor.attributes["shows"] == 1 + # Handle `requests` exception + requests_mock.get( + "/library/sections/2/all?includeCollections=0&type=2", + exc=requests.exceptions.ReadTimeout, + ) + trigger_plex_update( + mock_websocket, msgtype="status", payload=LIBRARY_UPDATE_PAYLOAD + ) + await hass.async_block_till_done() + + library_tv_sensor = hass.states.get("sensor.plex_server_1_library_tv_shows") + assert library_tv_sensor.state == STATE_UNAVAILABLE + + assert "Could not update library sensor" in caplog.text + + # Ensure sensor updates properly when it recovers + requests_mock.get( + "/library/sections/2/all?includeCollections=0&type=2", + text=library_tvshows_size, + ) + trigger_plex_update( + mock_websocket, msgtype="status", payload=LIBRARY_UPDATE_PAYLOAD + ) + await hass.async_block_till_done() + + library_tv_sensor = hass.states.get("sensor.plex_server_1_library_tv_shows") + assert library_tv_sensor.state == "10" + # Handle library deletion requests_mock.get( "/library/sections/2/all?includeCollections=0&type=2", status_code=404