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 migrationpull/48888/head
parent
1f80c756ab
commit
3ca69f5568
|
@ -18,6 +18,7 @@ from sqlalchemy.ext.declarative import declarative_base
|
|||
from sqlalchemy.orm import relationship
|
||||
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.helpers.json import JSONEncoder
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -53,7 +54,7 @@ class Events(Base): # type: ignore
|
|||
}
|
||||
__tablename__ = TABLE_EVENTS
|
||||
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"))
|
||||
origin = Column(String(32))
|
||||
time_fired = Column(DATETIME_TYPE, index=True)
|
||||
|
|
|
@ -22,6 +22,10 @@ ENTITY_MATCH_ALL = "all"
|
|||
# If no name is specified
|
||||
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_EVENT_SUNSET = "sunset"
|
||||
SUN_EVENT_SUNRISE = "sunrise"
|
||||
|
|
|
@ -58,12 +58,14 @@ from homeassistant.const import (
|
|||
EVENT_TIMER_OUT_OF_SYNC,
|
||||
LENGTH_METERS,
|
||||
MATCH_ALL,
|
||||
MAX_LENGTH_EVENT_TYPE,
|
||||
__version__,
|
||||
)
|
||||
from homeassistant.exceptions import (
|
||||
HomeAssistantError,
|
||||
InvalidEntityFormatError,
|
||||
InvalidStateError,
|
||||
MaxLengthExceeded,
|
||||
ServiceNotFound,
|
||||
Unauthorized,
|
||||
)
|
||||
|
@ -697,6 +699,9 @@ class EventBus:
|
|||
|
||||
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, [])
|
||||
|
||||
# EVENT_HOMEASSISTANT_CLOSE should go only to his listeners
|
||||
|
|
|
@ -154,3 +154,20 @@ class ServiceNotFound(HomeAssistantError):
|
|||
def __str__(self) -> str:
|
||||
"""Return string representation."""
|
||||
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 (
|
||||
InvalidEntityFormatError,
|
||||
InvalidStateError,
|
||||
MaxLengthExceeded,
|
||||
ServiceNotFound,
|
||||
)
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
@ -524,6 +525,21 @@ async def test_eventbus_coroutine_event_listener(hass):
|
|||
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():
|
||||
"""Test state.init."""
|
||||
with pytest.raises(InvalidEntityFormatError):
|
||||
|
|
Loading…
Reference in New Issue