From f5a862cb508dda5159fbf8d235f72f0552e750c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Wed, 20 Jun 2018 09:46:16 +0200 Subject: [PATCH] Make errors reported on init crash --- src/components/AppError.js | 23 ++++++++ src/components/RenderError.js | 97 +++++++++++++++++++++++++++++++ src/components/ThrowBlock.js | 85 +-------------------------- src/components/TranslatedError.js | 2 +- src/components/TriggerAppReady.js | 16 +++++ src/components/layout/Default.js | 5 +- src/renderer/init.js | 3 +- 7 files changed, 144 insertions(+), 87 deletions(-) create mode 100644 src/components/AppError.js create mode 100644 src/components/RenderError.js create mode 100644 src/components/TriggerAppReady.js diff --git a/src/components/AppError.js b/src/components/AppError.js new file mode 100644 index 00000000..7ae0ca90 --- /dev/null +++ b/src/components/AppError.js @@ -0,0 +1,23 @@ +// @flow + +import React from 'react' +import { ThemeProvider } from 'styled-components' +import { I18nextProvider } from 'react-i18next' +import theme from 'styles/theme' +import i18n from 'renderer/i18n/electron' +import TriggerAppReady from './TriggerAppReady' +import RenderError from './RenderError' + +// Like App except it just render an error + +const App = ({ language, error }: { error: Error, language: string }) => ( + + + + + + + +) + +export default App diff --git a/src/components/RenderError.js b/src/components/RenderError.js new file mode 100644 index 00000000..f8fb8a42 --- /dev/null +++ b/src/components/RenderError.js @@ -0,0 +1,97 @@ +// @flow + +import React, { PureComponent } from 'react' +import styled from 'styled-components' +import { shell, remote } from 'electron' +import qs from 'querystring' +import { translate } from 'react-i18next' + +import { rgba } from 'styles/helpers' +import db from 'helpers/db' + +import type { T } from 'types/common' + +import ExportLogsBtn from 'components/ExportLogsBtn' +import Box from 'components/base/Box' +import Button from 'components/base/Button' +import TranslatedError from './TranslatedError' + +type Props = { + error: Error, + t: T, + disableExport?: boolean, + children?: *, +} + +const Container = styled(Box).attrs({ + grow: true, + align: 'center', + justify: 'center', + bg: 'lightGraphite', + color: 'alertRed', + ff: 'Museo Sans|Bold', + flow: 2, +})`` + +const Inner = styled(Box).attrs({ + p: 2, + bg: p => rgba(p.theme.colors.alertRed, 0.05), + borderRadius: 1, +})` + border: ${p => `1px solid ${rgba(p.theme.colors.alertRed, 0.1)}`}; +` + +class RenderError extends PureComponent { + handleCreateIssue = () => { + const { error } = this.props + if (!error) { + return + } + const q = qs.stringify({ + title: `Error: ${error.message}`, + body: `Error was thrown: + +\`\`\` +${error.stack} +\`\`\` +`, + }) + shell.openExternal(`https://github.com/LedgerHQ/ledger-live-desktop/issues/new?${q}`) + } + + handleRestart = () => { + remote.app.relaunch() + remote.app.exit() + } + + handleReset = () => { + db.resetAll() + this.handleRestart() + } + + render() { + const { error, t, disableExport, children } = this.props + return ( + + + + + + + + {!disableExport ? : null} + + + {children} + + ) + } +} + +export default translate()(RenderError) diff --git a/src/components/ThrowBlock.js b/src/components/ThrowBlock.js index 4ca6a52e..89b0d497 100644 --- a/src/components/ThrowBlock.js +++ b/src/components/ThrowBlock.js @@ -1,49 +1,16 @@ // @flow - import logger from 'logger' import React, { PureComponent } from 'react' -import styled from 'styled-components' -import { shell, remote } from 'electron' -import qs from 'querystring' -import { translate } from 'react-i18next' - -import { rgba } from 'styles/helpers' -import db from 'helpers/db' - -import type { T } from 'types/common' - -import ExportLogsBtn from 'components/ExportLogsBtn' -import Box from 'components/base/Box' -import Button from 'components/base/Button' -import TranslatedError from './TranslatedError' +import RenderError from 'components/RenderError' type Props = { children: any, - t: T, } type State = { error: ?Error, } -const Container = styled(Box).attrs({ - grow: true, - align: 'center', - justify: 'center', - bg: 'lightGraphite', - color: 'alertRed', - ff: 'Museo Sans|Bold', - flow: 2, -})`` - -const Inner = styled(Box).attrs({ - p: 2, - bg: p => rgba(p.theme.colors.alertRed, 0.05), - borderRadius: 1, -})` - border: ${p => `1px solid ${rgba(p.theme.colors.alertRed, 0.1)}`}; -` - class ThrowBlock extends PureComponent { state = { error: null, @@ -54,59 +21,13 @@ class ThrowBlock extends PureComponent { this.setState({ error }) } - handleCreateIssue = () => { - const { error } = this.state - if (!error) { - return - } - const q = qs.stringify({ - title: `Error: ${error.message}`, - body: `Error was thrown: - -\`\`\` -${error.stack} -\`\`\` -`, - }) - shell.openExternal(`https://github.com/LedgerHQ/ledger-live-desktop/issues/new?${q}`) - } - - handleRestart = () => { - remote.app.relaunch() - remote.app.exit() - } - - handleReset = () => { - db.resetAll() - this.handleRestart() - } - render() { const { error } = this.state - const { t } = this.props if (error) { - return ( - - - - - - - - - - - - ) + return } return this.props.children } } -export default translate()(ThrowBlock) +export default ThrowBlock diff --git a/src/components/TranslatedError.js b/src/components/TranslatedError.js index d9d3f8b5..ff2ec07d 100644 --- a/src/components/TranslatedError.js +++ b/src/components/TranslatedError.js @@ -23,7 +23,7 @@ class TranslatedError extends PureComponent { if (translation) { return translation } - logger.warn('TranslatedError: no transation!', error.name, error) + logger.warn(`TranslatedError: no translation for '${error.name}'`, error) return error.message || error.name || t('errors:generic') } } diff --git a/src/components/TriggerAppReady.js b/src/components/TriggerAppReady.js new file mode 100644 index 00000000..e47f2ed2 --- /dev/null +++ b/src/components/TriggerAppReady.js @@ -0,0 +1,16 @@ +// @flow + +import { PureComponent } from 'react' + +export default class TriggerAppReady extends PureComponent<{}> { + componentDidMount() { + window.requestAnimationFrame(() => (this._timeout = setTimeout(() => window.onAppReady(), 300))) + } + componentWillUnmount() { + clearTimeout(this._timeout) + } + _timeout: * + render() { + return null + } +} diff --git a/src/components/layout/Default.js b/src/components/layout/Default.js index c9a16c8c..c107392e 100644 --- a/src/components/layout/Default.js +++ b/src/components/layout/Default.js @@ -19,6 +19,7 @@ import ExchangePage from 'components/ExchangePage' import SettingsPage from 'components/SettingsPage' import LibcoreBusyIndicator from 'components/LibcoreBusyIndicator' import DeviceBusyIndicator from 'components/DeviceBusyIndicator' +import TriggerAppReady from 'components/TriggerAppReady' import AppRegionDrag from 'components/AppRegionDrag' import IsUnlocked from 'components/IsUnlocked' @@ -41,7 +42,6 @@ type Props = { class Default extends Component { componentDidMount() { - window.requestAnimationFrame(() => (this._timeout = setTimeout(() => window.onAppReady(), 300))) window.addEventListener('keydown', this.kbShortcut) } @@ -59,7 +59,6 @@ class Default extends Component { } componentWillUnmount() { - clearTimeout(this._timeout) window.removeEventListener('keydown', this.kbShortcut) // Prevents adding multiple listeners when hot reloading } @@ -69,12 +68,12 @@ class Default extends Component { } } - _timeout = undefined _scrollContainer = null render() { return ( + {process.platform === 'darwin' && } diff --git a/src/renderer/init.js b/src/renderer/init.js index 0ad9407d..a91a2087 100644 --- a/src/renderer/init.js +++ b/src/renderer/init.js @@ -27,6 +27,7 @@ import hardReset from 'helpers/hardReset' import sentry from 'sentry/browser' import App from 'components/App' +import AppError from 'components/AppError' import 'styles/global' @@ -99,5 +100,5 @@ function r(Comp) { init().catch(e => { // for now we make the app crash instead of pending forever. later we can render the error OR try to recover, but probably this is unrecoverable cases. logger.error(e) - process.exit(1) + r() })