From 4dc106545b1f42535bf278ca4092a878515b614d Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 20 Jan 2025 14:00:08 -0800 Subject: [PATCH] add defensive checks against data being funny (#4633) --- reflex/app.py | 30 ++++++++++++++++++++++++++++-- reflex/utils/exceptions.py | 4 ++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/reflex/app.py b/reflex/app.py index 60be0d7dd..0d672e4c0 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -1557,10 +1557,36 @@ class EventNamespace(AsyncNamespace): Args: sid: The Socket.IO session id. data: The event data. + + Raises: + EventDeserializationError: If the event data is not a dictionary. """ fields = data - # Get the event. - event = Event(**{k: v for k, v in fields.items() if k in _EVENT_FIELDS}) + + if isinstance(fields, str): + console.warn( + "Received event data as a string. This generally should not happen and may indicate a bug." + f" Event data: {fields}" + ) + try: + fields = json.loads(fields) + except json.JSONDecodeError as ex: + raise exceptions.EventDeserializationError( + f"Failed to deserialize event data: {fields}." + ) from ex + + if not isinstance(fields, dict): + raise exceptions.EventDeserializationError( + f"Event data must be a dictionary, but received {fields} of type {type(fields)}." + ) + + try: + # Get the event. + event = Event(**{k: v for k, v in fields.items() if k in _EVENT_FIELDS}) + except (TypeError, ValueError) as ex: + raise exceptions.EventDeserializationError( + f"Failed to deserialize event data: {fields}." + ) from ex self.token_to_sid[event.token] = sid self.sid_to_token[sid] = event.token diff --git a/reflex/utils/exceptions.py b/reflex/utils/exceptions.py index 838d0a89d..37a68e420 100644 --- a/reflex/utils/exceptions.py +++ b/reflex/utils/exceptions.py @@ -187,6 +187,10 @@ class SystemPackageMissingError(ReflexError): """Raised when a system package is missing.""" +class EventDeserializationError(ReflexError, ValueError): + """Raised when an event cannot be deserialized.""" + + def raise_system_package_missing_error(package: str) -> NoReturn: """Raise a SystemPackageMissingError.