diff --git a/packages/web/src/Screen.js b/packages/web/src/Screen.js index 21876133d..54cc90e49 100644 --- a/packages/web/src/Screen.js +++ b/packages/web/src/Screen.js @@ -16,6 +16,7 @@ import DragAndDropFileTarget from './DragAndDropFileTarget'; import { useUploadsZone } from './utility/UploadsProvider'; import useTheme from './theme/useTheme'; import { MenuLayer } from './modals/showMenu'; +import ErrorBoundary from './utility/ErrorBoundary'; const BodyDiv = styled.div` position: fixed; @@ -113,7 +114,9 @@ export default function Screen() { {!!currentWidget && ( - + + + )} {!!currentWidget && ( diff --git a/packages/web/src/TabContent.js b/packages/web/src/TabContent.js index 5cf081330..9fde4573e 100644 --- a/packages/web/src/TabContent.js +++ b/packages/web/src/TabContent.js @@ -3,6 +3,7 @@ import _ from 'lodash'; import styled from 'styled-components'; import tabs from './tabs'; import { useOpenedTabs } from './utility/globalState'; +import ErrorBoundary from './utility/ErrorBoundary'; const TabContainer = styled.div` position: absolute; @@ -11,7 +12,7 @@ const TabContainer = styled.div` right: 0; bottom: 0; display: flex; - visibility: ${props => + visibility: ${(props) => // @ts-ignore props.tabVisible ? 'visible' : 'hidden'}; `; @@ -34,10 +35,10 @@ export default function TabContent({ toolbarPortalRef }) { // cleanup closed tabs if (_.difference(_.keys(mountedTabs), _.map(files, 'tabid')).length > 0) { - setMountedTabs(_.pickBy(mountedTabs, (v, k) => files.find(x => x.tabid == k))); + setMountedTabs(_.pickBy(mountedTabs, (v, k) => files.find((x) => x.tabid == k))); } - const selectedTab = files.find(x => x.selected); + const selectedTab = files.find((x) => x.selected); if (selectedTab) { const { tabid } = selectedTab; if (tabid && !mountedTabs[tabid]) @@ -47,13 +48,15 @@ export default function TabContent({ toolbarPortalRef }) { }); } - return _.keys(mountedTabs).map(tabid => { + return _.keys(mountedTabs).map((tabid) => { const { TabComponent, props } = mountedTabs[tabid]; const tabVisible = tabid == (selectedTab && selectedTab.tabid); return ( // @ts-ignore - + + + ); }); diff --git a/packages/web/src/modals/ModalBase.js b/packages/web/src/modals/ModalBase.js index d773153b1..72fc54585 100644 --- a/packages/web/src/modals/ModalBase.js +++ b/packages/web/src/modals/ModalBase.js @@ -2,6 +2,7 @@ import React from 'react'; import Modal from 'react-modal'; import styled from 'styled-components'; import useTheme from '../theme/useTheme'; +import ErrorBoundary from '../utility/ErrorBoundary'; // const StyledModal = styled(Modal)` // position: absolute; @@ -80,7 +81,7 @@ export default function ModalBase({ modalState, children, isFlex = false, fullSc // zIndex: 1200, // }} > - {children} + {children} ); } diff --git a/packages/web/src/utility/ErrorBoundary.js b/packages/web/src/utility/ErrorBoundary.js new file mode 100644 index 000000000..afe24816f --- /dev/null +++ b/packages/web/src/utility/ErrorBoundary.js @@ -0,0 +1,41 @@ +import React from 'react'; +import ErrorInfo from '../widgets/ErrorInfo'; + +export default class ErrorBoundary extends React.Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(error) { + // Update state so the next render will show the fallback UI. + return { + hasError: true, + error, + }; + } + componentDidCatch(error, errorInfo) { + // You can also log the error to an error reporting service + // logErrorToMyService(error, errorInfo); + console.error(error); + // console.log('errorInfo', errorInfo); + // console.log('error', error); + } + render() { + if (this.state.hasError) { + let message; + try { + message = (this.state.error.message || this.state.error).toString(); + } catch (e) { + message = 'Error detected'; + } + // You can render any custom fallback UI + return ( +
+ ; +
+ ); + } + return this.props.children; + } +}