|
@@ -2,14 +2,15 @@
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
-from typing import Dict, List, Tuple
|
|
|
+from typing import Dict, Tuple
|
|
|
|
|
|
-from reflex.compiler.compiler import _compile_component
|
|
|
from reflex.components.component import Component
|
|
|
-from reflex.components.el import div, p
|
|
|
-from reflex.event import EventHandler
|
|
|
+from reflex.components.datadisplay.logo import svg_logo
|
|
|
+from reflex.components.el import a, button, details, div, h2, hr, p, pre, summary
|
|
|
+from reflex.event import EventHandler, set_clipboard
|
|
|
from reflex.state import FrontendEventExceptionState
|
|
|
from reflex.vars.base import Var
|
|
|
+from reflex.vars.function import ArgsFunctionOperation
|
|
|
|
|
|
|
|
|
def on_error_spec(
|
|
@@ -40,38 +41,7 @@ class ErrorBoundary(Component):
|
|
|
on_error: EventHandler[on_error_spec]
|
|
|
|
|
|
# Rendered instead of the children when an error is caught.
|
|
|
- Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
|
|
|
- _var_type=Component
|
|
|
- )
|
|
|
-
|
|
|
- def add_custom_code(self) -> List[str]:
|
|
|
- """Add custom Javascript code into the page that contains this component.
|
|
|
-
|
|
|
- Custom code is inserted at module level, after any imports.
|
|
|
-
|
|
|
- Returns:
|
|
|
- The custom code to add.
|
|
|
- """
|
|
|
- fallback_container = div(
|
|
|
- p("Ooops...Unknown Reflex error has occured:"),
|
|
|
- p(
|
|
|
- Var(_js_expr="error.message"),
|
|
|
- color="red",
|
|
|
- ),
|
|
|
- p("Please contact the support."),
|
|
|
- )
|
|
|
-
|
|
|
- compiled_fallback = _compile_component(fallback_container)
|
|
|
-
|
|
|
- return [
|
|
|
- f"""
|
|
|
- function Fallback({{ error, resetErrorBoundary }}) {{
|
|
|
- return (
|
|
|
- {compiled_fallback}
|
|
|
- );
|
|
|
- }}
|
|
|
- """
|
|
|
- ]
|
|
|
+ fallback_render: Var[Component]
|
|
|
|
|
|
@classmethod
|
|
|
def create(cls, *children, **props):
|
|
@@ -86,6 +56,99 @@ class ErrorBoundary(Component):
|
|
|
"""
|
|
|
if "on_error" not in props:
|
|
|
props["on_error"] = FrontendEventExceptionState.handle_frontend_exception
|
|
|
+ if "fallback_render" not in props:
|
|
|
+ props["fallback_render"] = ArgsFunctionOperation.create(
|
|
|
+ ("event_args",),
|
|
|
+ Var.create(
|
|
|
+ div(
|
|
|
+ div(
|
|
|
+ div(
|
|
|
+ h2(
|
|
|
+ "An error occurred while rendering this page.",
|
|
|
+ font_size="1.25rem",
|
|
|
+ font_weight="bold",
|
|
|
+ ),
|
|
|
+ p(
|
|
|
+ "This is an error with the application itself.",
|
|
|
+ opacity="0.75",
|
|
|
+ ),
|
|
|
+ details(
|
|
|
+ summary("Error message", padding="0.5rem"),
|
|
|
+ div(
|
|
|
+ div(
|
|
|
+ pre(
|
|
|
+ Var(
|
|
|
+ _js_expr="event_args.error.stack",
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ padding="0.5rem",
|
|
|
+ width="fit-content",
|
|
|
+ ),
|
|
|
+ width="100%",
|
|
|
+ max_height="50vh",
|
|
|
+ overflow="auto",
|
|
|
+ background="#000",
|
|
|
+ color="#fff",
|
|
|
+ border_radius="0.25rem",
|
|
|
+ ),
|
|
|
+ button(
|
|
|
+ "Copy",
|
|
|
+ on_click=set_clipboard(
|
|
|
+ Var(_js_expr="event_args.error.stack"),
|
|
|
+ ),
|
|
|
+ padding="0.35rem 0.75rem",
|
|
|
+ margin="0.5rem",
|
|
|
+ background="#fff",
|
|
|
+ color="#000",
|
|
|
+ border="1px solid #000",
|
|
|
+ border_radius="0.25rem",
|
|
|
+ font_weight="bold",
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ display="flex",
|
|
|
+ flex_direction="column",
|
|
|
+ gap="1rem",
|
|
|
+ max_width="50ch",
|
|
|
+ border="1px solid #888888",
|
|
|
+ border_radius="0.25rem",
|
|
|
+ padding="1rem",
|
|
|
+ ),
|
|
|
+ hr(
|
|
|
+ border_color="currentColor",
|
|
|
+ opacity="0.25",
|
|
|
+ ),
|
|
|
+ a(
|
|
|
+ div(
|
|
|
+ "Built with ",
|
|
|
+ svg_logo("currentColor"),
|
|
|
+ display="flex",
|
|
|
+ align_items="baseline",
|
|
|
+ justify_content="center",
|
|
|
+ font_family="monospace",
|
|
|
+ gap="0.5rem",
|
|
|
+ ),
|
|
|
+ href="https://reflex.dev",
|
|
|
+ ),
|
|
|
+ display="flex",
|
|
|
+ flex_direction="column",
|
|
|
+ gap="1rem",
|
|
|
+ ),
|
|
|
+ height="100%",
|
|
|
+ width="100%",
|
|
|
+ position="absolute",
|
|
|
+ display="flex",
|
|
|
+ align_items="center",
|
|
|
+ justify_content="center",
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ _var_type=Component,
|
|
|
+ )
|
|
|
+ else:
|
|
|
+ props["fallback_render"] = ArgsFunctionOperation.create(
|
|
|
+ ("event_args",),
|
|
|
+ props["fallback_render"],
|
|
|
+ _var_type=Component,
|
|
|
+ )
|
|
|
return super().create(*children, **props)
|
|
|
|
|
|
|