Skip to content

feat: nullable exception handlers #5703

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be a tad better to check with is not None just in case a Var might come here, otherwise looks good!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adhami3310 thx, just fixed it

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
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