Fix generic camera error when template renders to an invalid URL (#109737)
This commit is contained in:
parent
45f44e9216
commit
94ccd59123
2 changed files with 34 additions and 3 deletions
|
@ -8,6 +8,7 @@ import logging
|
|||
from typing import Any
|
||||
|
||||
import httpx
|
||||
import voluptuous as vol
|
||||
import yarl
|
||||
|
||||
from homeassistant.components.camera import Camera, CameraEntityFeature
|
||||
|
@ -140,6 +141,12 @@ class GenericCamera(Camera):
|
|||
_LOGGER.error("Error parsing template %s: %s", self._still_image_url, err)
|
||||
return self._last_image
|
||||
|
||||
try:
|
||||
vol.Schema(vol.Url())(url)
|
||||
except vol.Invalid as err:
|
||||
_LOGGER.warning("Invalid URL '%s': %s, returning last image", url, err)
|
||||
return self._last_image
|
||||
|
||||
if url == self._last_url and self._limit_refetch:
|
||||
return self._last_image
|
||||
|
||||
|
|
|
@ -70,15 +70,20 @@ async def help_setup_mock_config_entry(
|
|||
|
||||
@respx.mock
|
||||
async def test_fetching_url(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, fakeimgbytes_png
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
fakeimgbytes_png,
|
||||
caplog: pytest.CaptureFixture,
|
||||
) -> None:
|
||||
"""Test that it fetches the given url."""
|
||||
respx.get("http://example.com").respond(stream=fakeimgbytes_png)
|
||||
hass.states.async_set("sensor.temp", "http://example.com/0a")
|
||||
respx.get("http://example.com/0a").respond(stream=fakeimgbytes_png)
|
||||
respx.get("http://example.com/1a").respond(stream=fakeimgbytes_png)
|
||||
|
||||
options = {
|
||||
"name": "config_test",
|
||||
"platform": "generic",
|
||||
"still_image_url": "http://example.com",
|
||||
"still_image_url": "{{ states.sensor.temp.state }}",
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
"authentication": "basic",
|
||||
|
@ -101,6 +106,25 @@ async def test_fetching_url(
|
|||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert respx.calls.call_count == 2
|
||||
|
||||
# If the template renders to an invalid URL we return the last image from cache
|
||||
hass.states.async_set("sensor.temp", "invalid url")
|
||||
|
||||
# sleep another .1 seconds to make cached image expire
|
||||
await asyncio.sleep(0.1)
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
assert respx.calls.call_count == 2
|
||||
assert (
|
||||
"Invalid URL 'invalid url': expected a URL, returning last image" in caplog.text
|
||||
)
|
||||
|
||||
# Restore a valid URL
|
||||
hass.states.async_set("sensor.temp", "http://example.com/1a")
|
||||
await asyncio.sleep(0.1)
|
||||
resp = await client.get("/api/camera_proxy/camera.config_test")
|
||||
assert resp.status == HTTPStatus.OK
|
||||
assert respx.calls.call_count == 3
|
||||
|
||||
|
||||
@respx.mock
|
||||
async def test_image_caching(
|
||||
|
|
Loading…
Add table
Reference in a new issue