diff --git a/src/error-boundary.js b/src/error-boundary.js new file mode 100644 index 0000000..9c9326f --- /dev/null +++ b/src/error-boundary.js @@ -0,0 +1,41 @@ +import React from 'react' + +// Based on https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary +const DEFAULT_ERROR = 'Your device doesn’t support rendering this map.' +class ErrorBoundary extends React.Component { + constructor(props) { + super(props) + this.state = { errorMessage: null } + } + + static getDerivedStateFromError(error) { + // Update state so the next render will show the fallback UI. + return { + errorMessage: error.message ?? defaultError, + } + } + + componentDidCatch(error, info) { + // Example "componentStack": + // in ComponentThatThrows (created by App) + // in ErrorBoundary (created by App) + // in div (created by App) + // in App + console.error(error, info.componentStack) + } + + render() { + if (this.state.errorMessage) { + // You can render any custom fallback UI + return ( +
+ {this.props.showErrorTrace ? this.state.errorMessage : DEFAULT_ERROR} +
+ ) + } + + return this.props.children + } +} + +export default ErrorBoundary diff --git a/src/map.js b/src/map.js index 121d8a0..fba6ad4 100644 --- a/src/map.js +++ b/src/map.js @@ -3,6 +3,7 @@ import Mapbox from './mapbox' import Regl from './regl' import { RegionProvider } from './region/context' import { LoadingProvider, LoadingUpdater } from './loading' +import ErrorBoundary from './error-boundary' const Map = ({ id, @@ -24,6 +25,7 @@ const Map = ({ setMetadataLoading, /** Tracks any requests of new chunks by containing `Raster` layers */ setChunkLoading, + showErrorTrace = false, }) => { return (
- - + - - - {children} - - - + + + + {children} + + + +
) }