diff --git a/reflex/app.py b/reflex/app.py index 7e40a95bf..69a5ff978 100644 --- a/reflex/app.py +++ b/reflex/app.py @@ -125,8 +125,8 @@ def default_backend_exception_handler(exception: Exception) -> EventSpec: ) if Toaster.is_used: return toast( + "An error occurred.", level="error", - title="An error occurred.", description="
".join(error_message), position="top-center", id="backend_error", diff --git a/reflex/components/sonner/toast.py b/reflex/components/sonner/toast.py index d4df31e82..e00eaad4e 100644 --- a/reflex/components/sonner/toast.py +++ b/reflex/components/sonner/toast.py @@ -4,6 +4,8 @@ from __future__ import annotations from typing import Any, ClassVar, Literal, Optional, Union +from pydantic import ValidationError + from reflex.base import Base from reflex.components.component import Component, ComponentNamespace from reflex.components.lucide.icon import Icon @@ -27,7 +29,6 @@ LiteralPosition = Literal[ "bottom-right", ] - toast_ref = Var.create_safe("refs['__toast']", _var_is_string=False) @@ -128,6 +129,24 @@ class ToastProps(PropsBase): # Function that gets called when the toast disappears automatically after it's timeout (duration` prop). on_auto_close: Optional[Any] + def __init__(self, **kwargs): + """Initialize the props. + + Args: + kwargs: Kwargs to initialize the props. + + Raises: + ValueError: If invalid props are passed on instantiation. + """ + try: + super().__init__(**kwargs) + except ValidationError as e: + invalid_fields = ", ".join([error["loc"][0] for error in e.errors()]) # type: ignore + supported_props_str = ", ".join(f'"{field}"' for field in self.get_fields()) + raise ValueError( + f"Invalid prop(s) {invalid_fields} for rx.toast. Supported props are {supported_props_str}" + ) from None + def dict(self, *args, **kwargs) -> dict[str, Any]: """Convert the object to a dictionary. @@ -159,6 +178,13 @@ class ToastProps(PropsBase): ) return d + class Config: + """Pydantic config.""" + + arbitrary_types_allowed = True + use_enum_values = True + extra = "forbid" + class Toaster(Component): """A Toaster Component for displaying toast notifications.""" diff --git a/reflex/components/sonner/toast.pyi b/reflex/components/sonner/toast.pyi index 7e5758b16..c7e626915 100644 --- a/reflex/components/sonner/toast.pyi +++ b/reflex/components/sonner/toast.pyi @@ -51,6 +51,11 @@ class ToastProps(PropsBase): def dict(self, *args, **kwargs) -> dict[str, Any]: ... + class Config: + arbitrary_types_allowed = True + use_enum_values = True + extra = "forbid" + class Toaster(Component): is_used: ClassVar[bool] = False diff --git a/tests/test_state.py b/tests/test_state.py index aa5705b09..1a014739d 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -1565,7 +1565,7 @@ async def test_state_with_invalid_yield(capsys, mock_app): assert update.events == rx.event.fix_events( [ rx.toast( - title="An error occurred.", + "An error occurred.", description="TypeError: Your handler test_state_with_invalid_yield..StateWithInvalidYield.invalid_handler must only return/yield: None, Events or other EventHandlers referenced by their class (not using `self`).
See logs for details.", level="error", id="backend_error",