summaryrefslogtreecommitdiffhomepage
path: root/gui/src/renderer/components
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2019-04-10 15:58:29 +0200
committerAndrej Mihajlov <and@mullvad.net>2019-04-11 14:30:26 +0200
commit1741fc096f01abc5fe5c1b5de84f8f504ed1615b (patch)
treefe02b281e42564fd4fc9990e12b824fa93e56641 /gui/src/renderer/components
parent336ca26d259d81d189faee521f4fd2cfa7d13f7e (diff)
downloadmullvadvpn-1741fc096f01abc5fe5c1b5de84f8f504ed1615b.tar.xz
mullvadvpn-1741fc096f01abc5fe5c1b5de84f8f504ed1615b.zip
Add error boundary
Diffstat (limited to 'gui/src/renderer/components')
-rw-r--r--gui/src/renderer/components/ErrorBoundary.tsx93
-rw-r--r--gui/src/renderer/components/Support.tsx13
2 files changed, 100 insertions, 6 deletions
diff --git a/gui/src/renderer/components/ErrorBoundary.tsx b/gui/src/renderer/components/ErrorBoundary.tsx
new file mode 100644
index 0000000000..07bc839bce
--- /dev/null
+++ b/gui/src/renderer/components/ErrorBoundary.tsx
@@ -0,0 +1,93 @@
+import log from 'electron-log';
+import * as React from 'react';
+import { Component, Styles, Text, View } from 'reactxp';
+import { colors, links } from '../../config.json';
+import { messages } from '../../shared/gettext';
+import PlatformWindowContainer from '../containers/PlatformWindowContainer';
+import ImageView from './ImageView';
+import { Container, Layout } from './Layout';
+
+interface IProps {
+ children?: React.ReactNode;
+}
+
+interface IState {
+ hasError: boolean;
+}
+
+const styles = {
+ container: Styles.createViewStyle({
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ backgroundColor: colors.blue,
+ }),
+ logo: Styles.createViewStyle({
+ marginBottom: 4,
+ }),
+ title: Styles.createTextStyle({
+ fontFamily: 'DINPro',
+ fontSize: 24,
+ fontWeight: '900',
+ lineHeight: 30,
+ letterSpacing: -0.5,
+ color: colors.white60,
+ marginBottom: 4,
+ }),
+ subtitle: Styles.createTextStyle({
+ fontFamily: 'Open Sans',
+ fontSize: 14,
+ lineHeight: 20,
+ color: colors.white40,
+ marginHorizontal: 20,
+ textAlign: 'center',
+ }),
+ email: Styles.createTextStyle({
+ fontWeight: '900',
+ }),
+};
+
+export default class ErrorBoundary extends Component<IProps, IState> {
+ public state = { hasError: false };
+
+ public componentDidCatch(error: Error, info: React.ErrorInfo) {
+ this.setState({ hasError: true });
+
+ log.error(
+ `The error boundary caught an error: ${error.message}\nError stack: ${error.stack ||
+ 'Not available'}\nComponent stack: ${info.componentStack}`,
+ );
+ }
+
+ public render() {
+ if (this.state.hasError) {
+ const reachBackMessage: React.ReactNodeArray =
+ // TRANSLATORS: The message displayed to the user in case of critical error in the GUI
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(email)s - support email
+ messages
+ .pgettext('error-boundary-view', 'Something went wrong. Please contact us at %(email)s')
+ .split('%(email)s', 2);
+ reachBackMessage.splice(1, 0, <Text style={styles.email}>{links.supportEmail}</Text>);
+
+ return (
+ <PlatformWindowContainer>
+ <Layout>
+ <Container>
+ <View style={styles.container}>
+ <ImageView height={120} width={120} source="logo-icon" style={styles.logo} />
+ <Text style={styles.title}>
+ {messages.pgettext('error-boundary-view', 'MULLVAD VPN')}
+ </Text>
+ <Text style={styles.subtitle}>{reachBackMessage}</Text>
+ </View>
+ </Container>
+ </Layout>
+ </PlatformWindowContainer>
+ );
+ } else {
+ return this.props.children;
+ }
+ }
+}
diff --git a/gui/src/renderer/components/Support.tsx b/gui/src/renderer/components/Support.tsx
index 439b229dfc..fd9241bbf8 100644
--- a/gui/src/renderer/components/Support.tsx
+++ b/gui/src/renderer/components/Support.tsx
@@ -293,12 +293,13 @@ export default class Support extends Component<ISupportProps, ISupportState> {
}
private renderSent() {
- // TRANSLATORS: The message displayed to the user after submitting the problem report, given that the user left his or her email for us to reach back.
- // TRANSLATORS: Available placeholders:
- // TRANSLATORS: %(email)s
- const reachBackMessage: React.ReactNodeArray = messages
- .pgettext('support-view', 'If needed we will contact you on %(email)s')
- .split('%(email)s', 2);
+ const reachBackMessage: React.ReactNodeArray =
+ // TRANSLATORS: The message displayed to the user after submitting the problem report, given that the user left his or her email for us to reach back.
+ // TRANSLATORS: Available placeholders:
+ // TRANSLATORS: %(email)s
+ messages
+ .pgettext('support-view', 'If needed we will contact you on %(email)s')
+ .split('%(email)s', 2);
reachBackMessage.splice(
1,
0,