add ErrorBoundary around layout outlet
Some checks failed
continuous-integration/drone/pr Build is failing

This commit is contained in:
Martti Malmi 2023-11-26 11:27:30 +02:00
parent 920f8ae20d
commit a592974b93
3 changed files with 85 additions and 40 deletions

View File

@ -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<ErrorBoundaryProps, ErrorBoundaryState> {
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 (
<div className="p-2">
<h1>Something went wrong.</h1>
<p>Error: {this.state.errorMessage}</p>
</div>
);
}
return this.props.children;
}
}

View File

@ -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({}),
}}>
<NavSidebar narrow={true} />
<div className="deck-cols">
{cols.map(c => {
switch (c) {
case "notes":
return <NotesCol />;
case "media":
return <MediaCol setThread={t => setDeckState({ thread: t })} />;
case "articles":
return <ArticlesCol />;
case "notifications":
return <NotificationsCol setThread={t => setDeckState({ thread: t })} />;
}
})}
</div>
{deckState.thread && (
<>
<Modal id="thread-overlay" onClose={() => setDeckState({})} className="thread-overlay thread">
<ThreadContextWrapper link={deckState.thread}>
<SpotlightFromThread onClose={() => setDeckState({})} />
<div>
<Thread onBack={() => setDeckState({})} disableSpotlight={true} />
<ErrorBoundary>
<div className="deck-cols">
{cols.map(c => {
switch (c) {
case "notes":
return <NotesCol />;
case "media":
return <MediaCol setThread={t => setDeckState({ thread: t })} />;
case "articles":
return <ArticlesCol />;
case "notifications":
return <NotificationsCol setThread={t => setDeckState({ thread: t })} />;
}
})}
</div>
{deckState.thread && (
<>
<Modal id="thread-overlay" onClose={() => setDeckState({})} className="thread-overlay thread">
<ThreadContextWrapper link={deckState.thread}>
<SpotlightFromThread onClose={() => setDeckState({})} />
<div>
<Thread onBack={() => setDeckState({})} disableSpotlight={true} />
</div>
</ThreadContextWrapper>
</Modal>
</>
)}
{deckState.article && (
<>
<Modal
id="thread-overlay-article"
onClose={() => setDeckState({})}
className="thread-overlay long-form"
onClick={() => setDeckState({})}>
<div onClick={e => e.stopPropagation()}>
<LongFormText ev={deckState.article} isPreview={false} related={[]} />
</div>
</ThreadContextWrapper>
</Modal>
</>
)}
{deckState.article && (
<>
<Modal
id="thread-overlay-article"
onClose={() => setDeckState({})}
className="thread-overlay long-form"
onClick={() => setDeckState({})}>
<div onClick={e => e.stopPropagation()}>
<LongFormText ev={deckState.article} isPreview={false} related={[]} />
</div>
</Modal>
</>
)}
<Toaster />
</Modal>
</>
)}
<Toaster />
</ErrorBoundary>
</DeckContext.Provider>
</div>
);

View File

@ -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() {
<div className="flex flex-row w-full">
<NavSidebar />
<div className="flex flex-1 flex-col overflow-x-hidden">
<Outlet />
<ErrorBoundary>
<Outlet />
</ErrorBoundary>
</div>
<RightColumn />
</div>