From 50f4ced894890101bd473c98257ae1f0e9339d6d Mon Sep 17 00:00:00 2001 From: nthouliss Date: Wed, 29 Mar 2023 11:30:44 +1100 Subject: [PATCH] Add error boundary --- src/preload.ts | 4 + .../managers/BrowserViewManagerPreload.ts | 4 + src/renderer/app/App.tsx | 9 +- src/renderer/common/ErrorBoundary.tsx | 87 +++++++++++++++++++ src/renderer/index.tsx | 33 +++---- 5 files changed, 120 insertions(+), 17 deletions(-) create mode 100644 src/renderer/common/ErrorBoundary.tsx diff --git a/src/preload.ts b/src/preload.ts index 668e4657..166b8d29 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -85,6 +85,10 @@ const api = { viewManager.removeBrowserView(id); ipcRenderer.send("AUDIO_CAPTURE_STOP_BROWSER_VIEW_STREAM", id); }, + removeAllBrowserViews: () => { + viewManager.removeAllBrowserViews(); + ipcRenderer.send("AUDIO_CAPTURE_STOP_ALL_BROWSER_VIEW_STREAMS"); + }, hideBrowserView: (id: number) => { viewManager.hideBrowserView(id); }, diff --git a/src/preload/managers/BrowserViewManagerPreload.ts b/src/preload/managers/BrowserViewManagerPreload.ts index 4ecd0a34..7e47ec93 100644 --- a/src/preload/managers/BrowserViewManagerPreload.ts +++ b/src/preload/managers/BrowserViewManagerPreload.ts @@ -30,6 +30,10 @@ export class BrowserViewManagerPreload { ipcRenderer.send("BROWSER_VIEW_REMOVE_BROWSER_VIEW", id); } + removeAllBrowserViews() { + ipcRenderer.send("BROWSER_VIEW_REMOVE_ALL_BROWSER_VIEWS"); + } + hideBrowserView(id: number) { ipcRenderer.send("BROWSER_VIEW_HIDE_BROWSER_VIEW", id); } diff --git a/src/renderer/app/App.tsx b/src/renderer/app/App.tsx index ca3a8ec6..eca193f2 100644 --- a/src/renderer/app/App.tsx +++ b/src/renderer/app/App.tsx @@ -63,12 +63,17 @@ export function App() { height="100%" alignItems="center" justifyContent="center" + gap={1} > - Fatal Error - {fatalError} + + Oops, something went wrong.. + + + {fatalError} + ); diff --git a/src/renderer/common/ErrorBoundary.tsx b/src/renderer/common/ErrorBoundary.tsx new file mode 100644 index 00000000..c8a39e25 --- /dev/null +++ b/src/renderer/common/ErrorBoundary.tsx @@ -0,0 +1,87 @@ +import React from "react"; + +import Stack from "@mui/material/Stack"; +import styled from "@mui/material/styles/styled"; +import Typography from "@mui/material/Typography"; + +import icon from "../../assets/icon.svg"; + +const WallPaper = styled("div")({ + position: "absolute", + width: "100%", + height: "100%", + top: 0, + left: 0, + overflow: "hidden", + background: "linear-gradient(#2D3143 0%, #1e2231 100%)", + zIndex: -1, +}); + +import { Component, ErrorInfo, ReactNode } from "react"; + +interface Props { + children?: ReactNode; +} + +interface State { + hasError: boolean; + error?: Error; + submitted?: boolean; +} + +class ErrorBoundary extends Component { + public state: State = { + hasError: false, + }; + + public static getDerivedStateFromError(error: Error): State { + // Update state so the next render will show the fallback UI. + return { hasError: true, error }; + } + + public componentDidCatch(error: Error, errorInfo: ErrorInfo) { + window.kenku.removeAllBrowserViews(); + console.error("Uncaught error:", error, errorInfo); + } + + public render() { + if (this.state.hasError) { + return ( + + + + + + + + Oops, something went wrong.. + + {this.state.error && ( + + {this.state.error.name}: {this.state.error.message} + + )} + {this.state.error?.stack && ( + + {this.state.error.stack} + + )} + + + ); + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx index e0adf73f..585af58e 100644 --- a/src/renderer/index.tsx +++ b/src/renderer/index.tsx @@ -10,22 +10,25 @@ import { PersistGate } from "redux-persist/integration/react"; import { App } from "./app/App"; import { theme } from "./app/theme"; import { store, persistor } from "./app/store"; +import ErrorBoundary from "./common/ErrorBoundary"; render( - - - - - } - persistor={persistor} - > - - - - - - , + + + + + + + } + persistor={persistor} + > + + + + + + , document.getElementById("root") );