diff --git a/desktop/app/src/init.tsx b/desktop/app/src/init.tsx index a9132fa7f..c67ec37e9 100644 --- a/desktop/app/src/init.tsx +++ b/desktop/app/src/init.tsx @@ -40,8 +40,15 @@ import { _setGlobalInteractionReporter, Logger, _LoggerContext, + Layout, + theme, } from 'flipper-plugin'; import isProduction from './utils/isProduction'; +import {Button, Input, Result, Typography} from 'antd'; +import constants from './fb-stubs/constants'; +import styled from '@emotion/styled'; +import {CopyOutlined} from '@ant-design/icons'; +import {clipboard} from 'electron/common'; if (process.env.NODE_ENV === 'development' && os.platform() === 'darwin') { // By default Node.JS has its internal certificate storage and doesn't use @@ -58,23 +65,93 @@ enableMapSet(); GK.init(); -const AppFrame = ({logger}: {logger: Logger}) => ( - <_LoggerContext.Provider value={logger}> - - - - - - <_NuxManagerContext.Provider value={_createNuxManager()}> - - - - - - - - -); +class AppFrame extends React.Component< + {logger: Logger}, + {error: any; errorInfo: any} +> { + state = {error: undefined as any, errorInfo: undefined as any}; + + getError() { + return this.state.error + ? `${this.state.error}\n\nComponent stack:\n${this.state.errorInfo?.componentStack}\n\nError stacktrace:\n${this.state.error?.stack}` + : ''; + } + + render() { + const {logger} = this.props; + return this.state.error ? ( + + + + A crash was detected in the Flipper chrome. Filing a{' '} + + bug report + {' '} + would be appreciated! Please include the details below. +

+ } + extra={[ + , + , + ]} + /> + +
+
+ ) : ( + <_LoggerContext.Provider value={logger}> + + + + + + <_NuxManagerContext.Provider value={_createNuxManager()}> + + + + + + + + + ); + } + + componentDidCatch(error: any, errorInfo: any) { + console.error( + `Flipper chrome crash: ${error}`, + error, + '\nComponents: ' + errorInfo?.componentStack, + ); + this.setState({ + error, + errorInfo, + }); + } +} function setProcessState(store: Store) { const settings = store.getState().settingsState; @@ -146,3 +223,10 @@ const persistor = persistStore(store, undefined, () => { }); setPersistor(persistor); + +const CodeBlock = styled(Input.TextArea)({ + fontFamily: + 'SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;', + fontSize: '0.8em', + color: theme.textColorSecondary, +}); diff --git a/desktop/flipper-plugin/src/ui/Layout.tsx b/desktop/flipper-plugin/src/ui/Layout.tsx index df20f0ff4..1b82e0982 100644 --- a/desktop/flipper-plugin/src/ui/Layout.tsx +++ b/desktop/flipper-plugin/src/ui/Layout.tsx @@ -139,6 +139,7 @@ type SplitLayoutProps = { */ center?: boolean; children: [React.ReactNode, React.ReactNode]; + style?: React.HTMLAttributes['style']; }; function renderSplitLayout(