mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Raise an exception when event_type exceeds the max length (#48115)
* raise an exception when event_type exceeds the max length that the recorder supports * add test * use max length constant in recorder * update config entry reloaded service name * remove exception string function because it's not needed * increase limit to 64 and revert event name change * fix test * assert exception args * fix test * add comment about migration
This commit is contained in:
parent
1f80c756ab
commit
3ca69f5568
@ -18,6 +18,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
|||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
from homeassistant.const import MAX_LENGTH_EVENT_TYPE
|
||||||
from homeassistant.core import Context, Event, EventOrigin, State, split_entity_id
|
from homeassistant.core import Context, Event, EventOrigin, State, split_entity_id
|
||||||
from homeassistant.helpers.json import JSONEncoder
|
from homeassistant.helpers.json import JSONEncoder
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
@ -53,7 +54,7 @@ class Events(Base): # type: ignore
|
|||||||
}
|
}
|
||||||
__tablename__ = TABLE_EVENTS
|
__tablename__ = TABLE_EVENTS
|
||||||
event_id = Column(Integer, primary_key=True)
|
event_id = Column(Integer, primary_key=True)
|
||||||
event_type = Column(String(64))
|
event_type = Column(String(MAX_LENGTH_EVENT_TYPE))
|
||||||
event_data = Column(Text().with_variant(mysql.LONGTEXT, "mysql"))
|
event_data = Column(Text().with_variant(mysql.LONGTEXT, "mysql"))
|
||||||
origin = Column(String(32))
|
origin = Column(String(32))
|
||||||
time_fired = Column(DATETIME_TYPE, index=True)
|
time_fired = Column(DATETIME_TYPE, index=True)
|
||||||
|
@ -22,6 +22,10 @@ ENTITY_MATCH_ALL = "all"
|
|||||||
# If no name is specified
|
# If no name is specified
|
||||||
DEVICE_DEFAULT_NAME = "Unnamed Device"
|
DEVICE_DEFAULT_NAME = "Unnamed Device"
|
||||||
|
|
||||||
|
# Max characters for an event_type (changing this requires a recorder
|
||||||
|
# database migration)
|
||||||
|
MAX_LENGTH_EVENT_TYPE = 64
|
||||||
|
|
||||||
# Sun events
|
# Sun events
|
||||||
SUN_EVENT_SUNSET = "sunset"
|
SUN_EVENT_SUNSET = "sunset"
|
||||||
SUN_EVENT_SUNRISE = "sunrise"
|
SUN_EVENT_SUNRISE = "sunrise"
|
||||||
|
@ -58,12 +58,14 @@ from homeassistant.const import (
|
|||||||
EVENT_TIMER_OUT_OF_SYNC,
|
EVENT_TIMER_OUT_OF_SYNC,
|
||||||
LENGTH_METERS,
|
LENGTH_METERS,
|
||||||
MATCH_ALL,
|
MATCH_ALL,
|
||||||
|
MAX_LENGTH_EVENT_TYPE,
|
||||||
__version__,
|
__version__,
|
||||||
)
|
)
|
||||||
from homeassistant.exceptions import (
|
from homeassistant.exceptions import (
|
||||||
HomeAssistantError,
|
HomeAssistantError,
|
||||||
InvalidEntityFormatError,
|
InvalidEntityFormatError,
|
||||||
InvalidStateError,
|
InvalidStateError,
|
||||||
|
MaxLengthExceeded,
|
||||||
ServiceNotFound,
|
ServiceNotFound,
|
||||||
Unauthorized,
|
Unauthorized,
|
||||||
)
|
)
|
||||||
@ -697,6 +699,9 @@ class EventBus:
|
|||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
|
if len(event_type) > MAX_LENGTH_EVENT_TYPE:
|
||||||
|
raise MaxLengthExceeded(event_type, "event_type", MAX_LENGTH_EVENT_TYPE)
|
||||||
|
|
||||||
listeners = self._listeners.get(event_type, [])
|
listeners = self._listeners.get(event_type, [])
|
||||||
|
|
||||||
# EVENT_HOMEASSISTANT_CLOSE should go only to his listeners
|
# EVENT_HOMEASSISTANT_CLOSE should go only to his listeners
|
||||||
|
@ -154,3 +154,20 @@ class ServiceNotFound(HomeAssistantError):
|
|||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
"""Return string representation."""
|
"""Return string representation."""
|
||||||
return f"Unable to find service {self.domain}.{self.service}"
|
return f"Unable to find service {self.domain}.{self.service}"
|
||||||
|
|
||||||
|
|
||||||
|
class MaxLengthExceeded(HomeAssistantError):
|
||||||
|
"""Raised when a property value has exceeded the max character length."""
|
||||||
|
|
||||||
|
def __init__(self, value: str, property_name: str, max_length: int) -> None:
|
||||||
|
"""Initialize error."""
|
||||||
|
super().__init__(
|
||||||
|
self,
|
||||||
|
(
|
||||||
|
f"Value {value} for property {property_name} has a max length of "
|
||||||
|
f"{max_length} characters"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
self.value = value
|
||||||
|
self.property_name = property_name
|
||||||
|
self.max_length = max_length
|
||||||
|
@ -36,6 +36,7 @@ import homeassistant.core as ha
|
|||||||
from homeassistant.exceptions import (
|
from homeassistant.exceptions import (
|
||||||
InvalidEntityFormatError,
|
InvalidEntityFormatError,
|
||||||
InvalidStateError,
|
InvalidStateError,
|
||||||
|
MaxLengthExceeded,
|
||||||
ServiceNotFound,
|
ServiceNotFound,
|
||||||
)
|
)
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
@ -524,6 +525,21 @@ async def test_eventbus_coroutine_event_listener(hass):
|
|||||||
assert len(coroutine_calls) == 1
|
assert len(coroutine_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_eventbus_max_length_exceeded(hass):
|
||||||
|
"""Test that an exception is raised when the max character length is exceeded."""
|
||||||
|
|
||||||
|
long_evt_name = (
|
||||||
|
"this_event_exceeds_the_max_character_length_even_with_the_new_limit"
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(MaxLengthExceeded) as exc_info:
|
||||||
|
hass.bus.async_fire(long_evt_name)
|
||||||
|
|
||||||
|
assert exc_info.value.property_name == "event_type"
|
||||||
|
assert exc_info.value.max_length == 64
|
||||||
|
assert exc_info.value.value == long_evt_name
|
||||||
|
|
||||||
|
|
||||||
def test_state_init():
|
def test_state_init():
|
||||||
"""Test state.init."""
|
"""Test state.init."""
|
||||||
with pytest.raises(InvalidEntityFormatError):
|
with pytest.raises(InvalidEntityFormatError):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user