Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions reflex/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,14 +422,14 @@ class App(MiddlewareMixin, LifespanMixin):
_background_tasks: set[asyncio.Task] = dataclasses.field(default_factory=set)

# Frontend Error Handler Function
frontend_exception_handler: Callable[[Exception], None] = (
frontend_exception_handler: Callable[[Exception], None] | None = (
default_frontend_exception_handler
)

# Backend Error Handler Function
backend_exception_handler: Callable[
[Exception], EventSpec | list[EventSpec] | None
] = default_backend_exception_handler
backend_exception_handler: (
Callable[[Exception], EventSpec | list[EventSpec] | None] | None
) = default_backend_exception_handler

# Put the toast provider in the app wrap.
toaster: Component | None = dataclasses.field(default_factory=toast.provider)
Expand Down Expand Up @@ -1620,6 +1620,10 @@ def _validate_exception_handlers(self):
],
strict=True,
):
if handler_fn is None:
# If the handler is None, skip validation.
continue

if hasattr(handler_fn, "__name__"):
_fn_name = handler_fn.__name__
else:
Expand Down Expand Up @@ -1665,7 +1669,10 @@ def _validate_exception_handlers(self):
raise ValueError(msg)

# Check if the return type is valid for backend exception handler
if handler_domain == "backend":
if (
handler_domain == "backend"
and self.backend_exception_handler is not None
):
sig = inspect.signature(self.backend_exception_handler)
return_type = (
eval(sig.return_annotation)
Expand Down Expand Up @@ -1773,7 +1780,8 @@ async def process(
except Exception as ex:
telemetry.send_error(ex, context="backend")

app.backend_exception_handler(ex)
if app.backend_exception_handler is not None:
app.backend_exception_handler(ex)
raise


Expand Down
18 changes: 13 additions & 5 deletions reflex/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1742,8 +1742,11 @@ async def _as_state_update(
except Exception as ex:
state._clean()

app = prerequisites.get_and_validate_app().app
event_specs = (
prerequisites.get_and_validate_app().app.backend_exception_handler(ex)
app.backend_exception_handler(ex)
if app.backend_exception_handler is not None
else None
)

if event_specs is None:
Expand Down Expand Up @@ -1880,8 +1883,12 @@ async def _process_event(
except Exception as ex:
telemetry.send_error(ex, context="backend")

app = prerequisites.get_and_validate_app().app

event_specs = (
prerequisites.get_and_validate_app().app.backend_exception_handler(ex)
app.backend_exception_handler(ex)
if app.backend_exception_handler is not None
else None
)

yield await state._as_state_update(
Expand Down Expand Up @@ -2433,9 +2440,10 @@ def handle_frontend_exception(self, info: str, component_stack: str) -> None:
component_stack: The stack trace of the component where the exception occurred.

"""
prerequisites.get_and_validate_app().app.frontend_exception_handler(
Exception(info)
)
app = prerequisites.get_and_validate_app().app

if app.frontend_exception_handler is not None:
app.frontend_exception_handler(Exception(info))


class UpdateVarsInternalState(State):
Expand Down
Loading