error_boundary.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """A React Error Boundary component that catches unhandled frontend exceptions."""
  2. from __future__ import annotations
  3. from typing import List
  4. from reflex.compiler.compiler import _compile_component
  5. from reflex.components.component import Component
  6. from reflex.components.el import div, p
  7. from reflex.constants import Hooks, Imports
  8. from reflex.event import EventChain, EventHandler
  9. from reflex.utils.imports import ImportVar
  10. from reflex.vars.base import Var
  11. from reflex.vars.function import FunctionVar
  12. class ErrorBoundary(Component):
  13. """A React Error Boundary component that catches unhandled frontend exceptions."""
  14. library = "react-error-boundary"
  15. tag = "ErrorBoundary"
  16. # Fired when the boundary catches an error.
  17. on_error: EventHandler[lambda error, info: [error, info]] = Var( # type: ignore
  18. "logFrontendError"
  19. ).to(FunctionVar, EventChain)
  20. # Rendered instead of the children when an error is caught.
  21. Fallback_component: Var[Component] = Var(_js_expr="Fallback")._replace(
  22. _var_type=Component
  23. )
  24. def add_imports(self) -> dict[str, list[ImportVar]]:
  25. """Add imports for the component.
  26. Returns:
  27. The imports to add.
  28. """
  29. return Imports.EVENTS
  30. def add_hooks(self) -> List[str | Var]:
  31. """Add hooks for the component.
  32. Returns:
  33. The hooks to add.
  34. """
  35. return [Hooks.EVENTS, Hooks.FRONTEND_ERRORS]
  36. def add_custom_code(self) -> List[str]:
  37. """Add custom Javascript code into the page that contains this component.
  38. Custom code is inserted at module level, after any imports.
  39. Returns:
  40. The custom code to add.
  41. """
  42. fallback_container = div(
  43. p("Ooops...Unknown Reflex error has occured:"),
  44. p(
  45. Var(_js_expr="error.message"),
  46. color="red",
  47. ),
  48. p("Please contact the support."),
  49. )
  50. compiled_fallback = _compile_component(fallback_container)
  51. return [
  52. f"""
  53. function Fallback({{ error, resetErrorBoundary }}) {{
  54. return (
  55. {compiled_fallback}
  56. );
  57. }}
  58. """
  59. ]
  60. error_boundary = ErrorBoundary.create