add type hinting to error boundary (#4182)
* add type hinting to error boundary * remove logFrontendError * fix other calls to handle_frontend_exception
This commit is contained in:
parent
54ad9f0f4b
commit
45959881ac
@ -743,6 +743,7 @@ export const useEventLoop = (
|
|||||||
addEvents([
|
addEvents([
|
||||||
Event(`${exception_state_name}.handle_frontend_exception`, {
|
Event(`${exception_state_name}.handle_frontend_exception`, {
|
||||||
stack: error.stack,
|
stack: error.stack,
|
||||||
|
component_stack: "",
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
return false;
|
return false;
|
||||||
@ -754,6 +755,7 @@ export const useEventLoop = (
|
|||||||
addEvents([
|
addEvents([
|
||||||
Event(`${exception_state_name}.handle_frontend_exception`, {
|
Event(`${exception_state_name}.handle_frontend_exception`, {
|
||||||
stack: event.reason.stack,
|
stack: event.reason.stack,
|
||||||
|
component_stack: "",
|
||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,16 +2,30 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import List
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
from reflex.compiler.compiler import _compile_component
|
from reflex.compiler.compiler import _compile_component
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.components.el import div, p
|
from reflex.components.el import div, p
|
||||||
from reflex.constants import Hooks, Imports
|
from reflex.event import EventHandler
|
||||||
from reflex.event import EventChain, EventHandler
|
from reflex.state import FrontendEventExceptionState
|
||||||
from reflex.utils.imports import ImportVar
|
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
from reflex.vars.function import FunctionVar
|
|
||||||
|
|
||||||
|
def on_error_spec(error: Var, info: Var[Dict[str, str]]) -> Tuple[Var[str], Var[str]]:
|
||||||
|
"""The spec for the on_error event handler.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
error: The error message.
|
||||||
|
info: Additional information about the error.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The arguments for the event handler.
|
||||||
|
"""
|
||||||
|
return (
|
||||||
|
error.stack,
|
||||||
|
info.componentStack,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ErrorBoundary(Component):
|
class ErrorBoundary(Component):
|
||||||
@ -21,31 +35,13 @@ class ErrorBoundary(Component):
|
|||||||
tag = "ErrorBoundary"
|
tag = "ErrorBoundary"
|
||||||
|
|
||||||
# Fired when the boundary catches an error.
|
# Fired when the boundary catches an error.
|
||||||
on_error: EventHandler[lambda error, info: [error, info]] = Var( # type: ignore
|
on_error: EventHandler[on_error_spec]
|
||||||
"logFrontendError"
|
|
||||||
).to(FunctionVar, EventChain)
|
|
||||||
|
|
||||||
# Rendered instead of the children when an error is caught.
|
# Rendered instead of the children when an error is caught.
|
||||||
Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
|
Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
|
||||||
_var_type=Component
|
_var_type=Component
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_imports(self) -> dict[str, list[ImportVar]]:
|
|
||||||
"""Add imports for the component.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The imports to add.
|
|
||||||
"""
|
|
||||||
return Imports.EVENTS
|
|
||||||
|
|
||||||
def add_hooks(self) -> List[str | Var]:
|
|
||||||
"""Add hooks for the component.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The hooks to add.
|
|
||||||
"""
|
|
||||||
return [Hooks.EVENTS, Hooks.FRONTEND_ERRORS]
|
|
||||||
|
|
||||||
def add_custom_code(self) -> List[str]:
|
def add_custom_code(self) -> List[str]:
|
||||||
"""Add custom Javascript code into the page that contains this component.
|
"""Add custom Javascript code into the page that contains this component.
|
||||||
|
|
||||||
@ -75,5 +71,20 @@ class ErrorBoundary(Component):
|
|||||||
"""
|
"""
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create(cls, *children, **props):
|
||||||
|
"""Create an ErrorBoundary component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
*children: The children of the component.
|
||||||
|
**props: The props of the component.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The ErrorBoundary component.
|
||||||
|
"""
|
||||||
|
if "on_error" not in props:
|
||||||
|
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
||||||
|
return super().create(*children, **props)
|
||||||
|
|
||||||
|
|
||||||
error_boundary = ErrorBoundary.create
|
error_boundary = ErrorBoundary.create
|
||||||
|
@ -3,17 +3,18 @@
|
|||||||
# ------------------- DO NOT EDIT ----------------------
|
# ------------------- DO NOT EDIT ----------------------
|
||||||
# This file was generated by `reflex/utils/pyi_generator.py`!
|
# This file was generated by `reflex/utils/pyi_generator.py`!
|
||||||
# ------------------------------------------------------
|
# ------------------------------------------------------
|
||||||
from typing import Any, Dict, List, Optional, Union, overload
|
from typing import Any, Dict, List, Optional, Tuple, Union, overload
|
||||||
|
|
||||||
from reflex.components.component import Component
|
from reflex.components.component import Component
|
||||||
from reflex.event import EventType
|
from reflex.event import EventType
|
||||||
from reflex.style import Style
|
from reflex.style import Style
|
||||||
from reflex.utils.imports import ImportVar
|
|
||||||
from reflex.vars.base import Var
|
from reflex.vars.base import Var
|
||||||
|
|
||||||
|
def on_error_spec(
|
||||||
|
error: Var, info: Var[Dict[str, str]]
|
||||||
|
) -> Tuple[Var[str], Var[str]]: ...
|
||||||
|
|
||||||
class ErrorBoundary(Component):
|
class ErrorBoundary(Component):
|
||||||
def add_imports(self) -> dict[str, list[ImportVar]]: ...
|
|
||||||
def add_hooks(self) -> List[str | Var]: ...
|
|
||||||
def add_custom_code(self) -> List[str]: ...
|
def add_custom_code(self) -> List[str]: ...
|
||||||
@overload
|
@overload
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -31,7 +32,7 @@ class ErrorBoundary(Component):
|
|||||||
on_click: Optional[EventType[[]]] = None,
|
on_click: Optional[EventType[[]]] = None,
|
||||||
on_context_menu: Optional[EventType[[]]] = None,
|
on_context_menu: Optional[EventType[[]]] = None,
|
||||||
on_double_click: Optional[EventType[[]]] = None,
|
on_double_click: Optional[EventType[[]]] = None,
|
||||||
on_error: Optional[EventType] = None,
|
on_error: Optional[EventType[str, str]] = None,
|
||||||
on_focus: Optional[EventType[[]]] = None,
|
on_focus: Optional[EventType[[]]] = None,
|
||||||
on_mount: Optional[EventType[[]]] = None,
|
on_mount: Optional[EventType[[]]] = None,
|
||||||
on_mouse_down: Optional[EventType[[]]] = None,
|
on_mouse_down: Optional[EventType[[]]] = None,
|
||||||
@ -45,7 +46,7 @@ class ErrorBoundary(Component):
|
|||||||
on_unmount: Optional[EventType[[]]] = None,
|
on_unmount: Optional[EventType[[]]] = None,
|
||||||
**props,
|
**props,
|
||||||
) -> "ErrorBoundary":
|
) -> "ErrorBoundary":
|
||||||
"""Create the component.
|
"""Create an ErrorBoundary component.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
*children: The children of the component.
|
*children: The children of the component.
|
||||||
@ -59,7 +60,7 @@ class ErrorBoundary(Component):
|
|||||||
**props: The props of the component.
|
**props: The props of the component.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The component.
|
The ErrorBoundary component.
|
||||||
"""
|
"""
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -132,16 +132,6 @@ class Hooks(SimpleNamespace):
|
|||||||
}
|
}
|
||||||
})"""
|
})"""
|
||||||
|
|
||||||
FRONTEND_ERRORS = f"""
|
|
||||||
const logFrontendError = (error, info) => {{
|
|
||||||
if (process.env.NODE_ENV === "production") {{
|
|
||||||
addEvents([Event("{CompileVars.FRONTEND_EXCEPTION_STATE_FULL}.handle_frontend_exception", {{
|
|
||||||
stack: error.stack,
|
|
||||||
}})])
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
class MemoizationDisposition(enum.Enum):
|
class MemoizationDisposition(enum.Enum):
|
||||||
"""The conditions under which a component should be memoized."""
|
"""The conditions under which a component should be memoized."""
|
||||||
|
@ -39,6 +39,7 @@ from typing import (
|
|||||||
from sqlalchemy.orm import DeclarativeBase
|
from sqlalchemy.orm import DeclarativeBase
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
from reflex import event
|
||||||
from reflex.config import get_config
|
from reflex.config import get_config
|
||||||
from reflex.istate.data import RouterData
|
from reflex.istate.data import RouterData
|
||||||
from reflex.vars.base import (
|
from reflex.vars.base import (
|
||||||
@ -2094,7 +2095,8 @@ class State(BaseState):
|
|||||||
class FrontendEventExceptionState(State):
|
class FrontendEventExceptionState(State):
|
||||||
"""Substate for handling frontend exceptions."""
|
"""Substate for handling frontend exceptions."""
|
||||||
|
|
||||||
def handle_frontend_exception(self, stack: str) -> None:
|
@event
|
||||||
|
def handle_frontend_exception(self, stack: str, component_stack: str) -> None:
|
||||||
"""Handle frontend exceptions.
|
"""Handle frontend exceptions.
|
||||||
|
|
||||||
If a frontend exception handler is provided, it will be called.
|
If a frontend exception handler is provided, it will be called.
|
||||||
@ -2102,6 +2104,7 @@ class FrontendEventExceptionState(State):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
stack: The stack trace of the exception.
|
stack: The stack trace of the exception.
|
||||||
|
component_stack: The stack trace of the component where the exception occurred.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
app_instance = getattr(prerequisites.get_app(), constants.CompileVars.APP)
|
app_instance = getattr(prerequisites.get_app(), constants.CompileVars.APP)
|
||||||
|
Loading…
Reference in New Issue
Block a user