From c1f5e55a02f7474b675c6d250f16e4cde800e951 Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Mon, 12 May 2025 16:34:39 -0700 Subject: [PATCH 1/2] allow eventhandlers and eventspecs for exception handlers --- reflex/state.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/reflex/state.py b/reflex/state.py index d864391988f..49fef5d548e 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -2359,7 +2359,7 @@ class FrontendEventExceptionState(State): """Substate for handling frontend exceptions.""" @event - def handle_frontend_exception(self, stack: str, component_stack: str) -> None: + def handle_frontend_exception(self, stack: str, component_stack: str): """Handle frontend exceptions. If a frontend exception handler is provided, it will be called. @@ -2369,10 +2369,25 @@ def handle_frontend_exception(self, stack: str, component_stack: str) -> None: stack: The stack trace of the exception. component_stack: The stack trace of the component where the exception occurred. + Returns: + Chained event specs to be executed. """ - prerequisites.get_and_validate_app().app.frontend_exception_handler( + frontend_exception_handler = ( + prerequisites.get_and_validate_app().app.frontend_exception_handler + ) + + if isinstance(frontend_exception_handler, EventSpec) and callable( + frontend_exception_handler + ): + return frontend_exception_handler(stack) + value = prerequisites.get_and_validate_app().app.frontend_exception_handler( Exception(stack) ) + if value is not None: + console.warn( + f"Frontend exception handler returned a value: {value}. This is not supported with plain functions." + " Consider using an Event in a state class instead." + ) class UpdateVarsInternalState(State): From c02e00c30449894edb1d8d047d95c6f3ef94d08f Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Wed, 14 May 2025 18:50:26 -0700 Subject: [PATCH 2/2] make frontend event handler type checking a tad better --- reflex/state.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/reflex/state.py b/reflex/state.py index 49fef5d548e..05b4d1cccea 100644 --- a/reflex/state.py +++ b/reflex/state.py @@ -42,6 +42,7 @@ from reflex.event import ( BACKGROUND_TASK_MARKER, Event, + EventActionsMixin, EventHandler, EventSpec, fix_events, @@ -2371,18 +2372,23 @@ def handle_frontend_exception(self, stack: str, component_stack: str): Returns: Chained event specs to be executed. + + Raises: + TypeError: If the frontend exception handler is not callable. """ frontend_exception_handler = ( prerequisites.get_and_validate_app().app.frontend_exception_handler ) - if isinstance(frontend_exception_handler, EventSpec) and callable( + if isinstance(frontend_exception_handler, EventActionsMixin) and callable( frontend_exception_handler ): return frontend_exception_handler(stack) - value = prerequisites.get_and_validate_app().app.frontend_exception_handler( - Exception(stack) - ) + if not callable(frontend_exception_handler): + raise TypeError( + f"Frontend exception handler must be callable. Got {type(frontend_exception_handler)}." + ) + value = frontend_exception_handler(Exception(stack)) if value is not None: console.warn( f"Frontend exception handler returned a value: {value}. This is not supported with plain functions."