diff --git a/src/components/errorBoundaries/panelErrorBoundary.tsx b/src/components/errorBoundaries/panelErrorBoundary.tsx new file mode 100644 index 000000000..a2c7ad5a5 --- /dev/null +++ b/src/components/errorBoundaries/panelErrorBoundary.tsx @@ -0,0 +1,80 @@ +import React from "react"; +import styled from "styled-components"; + +const Background = styled.div` + background: repeating-linear-gradient( + 45deg, + transparent, + transparent 20px, + #f4d2ff 20px, + #f4d2ff 21px + ); + margin: 10px 10px; + padding: 10px 10px; + border: 1px solid #f4d2ff; + display: inline-block; + position: relative; +`; + +interface Props { + width: number; + height: number; + name: string; +} +interface State { + hasError: boolean; + errorMessage: string; +} + +class PanelErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false, errorMessage: ''}; + } + static getDerivedStateFromError(error) { + // Update state so the next render will show the fallback UI. + return { + hasError: true, + errorMessage: error instanceof Error ? error.message : "Unknown error (thrown value was not an instance of Error)", + }; + } + override componentDidCatch(error, info) { + // You can also log the error to an error reporting service + console.error(error); + console.error(info); + } + + override render() { + if (!this.state.hasError) return this.props.children; + + /** + * We could add something like + * + * but it risks rendering an incorrect state so I'd prefer not to + */ + + return ( + +

{`Error! Something's gone wrong within the ${this.props.name} panel`}

+ +

+ {`Error message: "${this.state.errorMessage}"`} +

+ +

+ {'Please consider making a bug report either on '} + GitHub + {' or via '} + email. + (The more information you can include the better - things such as steps to reproduce the bug, your browser version, the version of Auspice etc are incredibly helpful.) +

+

+ In the meantime you could try refreshing the page which may fix things in the short term. +

+ +
+ ); + } +} + +export default PanelErrorBoundary; diff --git a/src/components/main/index.js b/src/components/main/index.js index 87fce0374..7c3c5b1f3 100644 --- a/src/components/main/index.js +++ b/src/components/main/index.js @@ -23,6 +23,7 @@ import ErrorBoundary from "../../util/errorBoundary"; import Spinner, { PanelSpinner } from "../framework/spinner"; import MainDisplayMarkdown from "../narrative/MainDisplayMarkdown"; import MobileNarrativeDisplay from "../narrative/MobileNarrativeDisplay"; +import PanelErrorBoundary from "../errorBoundaries/panelErrorBoundary"; const Entropy = lazy(() => import("../entropy")); const Frequencies = lazy(() => import("../frequencies")); @@ -155,11 +156,17 @@ class Main extends React.Component { } {this.props.displayNarrative || this.props.showOnlyPanels ? null : } {this.props.panelsToDisplay.includes("tree") ? - : + name="tree" + > + + : null } {this.props.panelsToDisplay.includes("measurements") ? @@ -172,34 +179,50 @@ class Main extends React.Component { /> } > - + name="measurements" + > + + : null } {this.props.panelsToDisplay.includes("map") ? - : + name="map" + > + + : null } {this.props.panelsToDisplay.includes("entropy") ? ( - + + + ) : null } {this.props.panelsToDisplay.includes("frequencies") && this.props.frequenciesLoaded ? ( - + + + ) : null }