diff --git a/packages/app/src/Element/ErrorBoundary.tsx b/packages/app/src/Element/ErrorBoundary.tsx new file mode 100644 index 00000000..9793e7a1 --- /dev/null +++ b/packages/app/src/Element/ErrorBoundary.tsx @@ -0,0 +1,39 @@ +import React from "react"; + +interface ErrorBoundaryState { + hasError: boolean; + errorMessage?: string; +} + +interface ErrorBoundaryProps { + children: React.ReactNode; +} + +export default class ErrorBoundary extends React.Component { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error: Error): ErrorBoundaryState { + return { hasError: true, errorMessage: error.message }; + } + + componentDidCatch(error: Error, errorInfo: React.ErrorInfo) { + console.error("Caught an error:", error, errorInfo); + } + + render() { + if (this.state.hasError) { + // Render any custom fallback UI with the error message + return ( +
+

Something went wrong.

+

Error: {this.state.errorMessage}

+
+ ); + } + + return this.props.children; + } +} diff --git a/packages/app/src/Pages/DeckLayout.tsx b/packages/app/src/Pages/DeckLayout.tsx index a87c658f..014fc12c 100644 --- a/packages/app/src/Pages/DeckLayout.tsx +++ b/packages/app/src/Pages/DeckLayout.tsx @@ -22,6 +22,7 @@ import Toaster from "@/Toaster"; import useLogin from "@/Hooks/useLogin"; import { LongFormText } from "@/Element/Event/LongFormText"; import NavSidebar from "@/Pages/Layout/NavSidebar"; +import ErrorBoundary from "@/Element/ErrorBoundary"; type Cols = "notes" | "articles" | "media" | "streams" | "notifications"; @@ -68,46 +69,48 @@ export function SnortDeckLayout() { reset: () => setDeckState({}), }}> -
- {cols.map(c => { - switch (c) { - case "notes": - return ; - case "media": - return setDeckState({ thread: t })} />; - case "articles": - return ; - case "notifications": - return setDeckState({ thread: t })} />; - } - })} -
- {deckState.thread && ( - <> - setDeckState({})} className="thread-overlay thread"> - - setDeckState({})} /> -
- setDeckState({})} disableSpotlight={true} /> + +
+ {cols.map(c => { + switch (c) { + case "notes": + return ; + case "media": + return setDeckState({ thread: t })} />; + case "articles": + return ; + case "notifications": + return setDeckState({ thread: t })} />; + } + })} +
+ {deckState.thread && ( + <> + setDeckState({})} className="thread-overlay thread"> + + setDeckState({})} /> +
+ setDeckState({})} disableSpotlight={true} /> +
+
+
+ + )} + {deckState.article && ( + <> + setDeckState({})} + className="thread-overlay long-form" + onClick={() => setDeckState({})}> +
e.stopPropagation()}> +
- -
- - )} - {deckState.article && ( - <> - setDeckState({})} - className="thread-overlay long-form" - onClick={() => setDeckState({})}> -
e.stopPropagation()}> - -
-
- - )} - + + + )} + +
); diff --git a/packages/app/src/Pages/Layout/index.tsx b/packages/app/src/Pages/Layout/index.tsx index 89b18e76..fc6f66ce 100644 --- a/packages/app/src/Pages/Layout/index.tsx +++ b/packages/app/src/Pages/Layout/index.tsx @@ -17,6 +17,7 @@ import AccountHeader from "./AccountHeader"; import RightColumn from "./RightColumn"; import { LogoHeader } from "./LogoHeader"; import useLoginFeed from "@/Feed/LoginFeed"; +import ErrorBoundary from "@/Element/ErrorBoundary"; export default function Index() { const location = useLocation(); @@ -62,7 +63,9 @@ export default function Index() {
- + + +