about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/components/error_boundary.js
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2018-11-28 15:01:40 +0100
committerThibG <thib@sitedethib.com>2018-11-28 22:36:01 +0100
commit922d05864f4ba37a4026cd5f7e6e6ed5417a7404 (patch)
treea157d4c4e3188d3e7de34793263ce1dce8dedefa /app/javascript/flavours/glitch/components/error_boundary.js
parent39c8a71df80d303ee08d24b3ce3a66400a1dcc0b (diff)
Add error boundary component to catch Web UI crashes
Diffstat (limited to 'app/javascript/flavours/glitch/components/error_boundary.js')
-rw-r--r--app/javascript/flavours/glitch/components/error_boundary.js92
1 files changed, 92 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/components/error_boundary.js b/app/javascript/flavours/glitch/components/error_boundary.js
new file mode 100644
index 000000000..fd37383f2
--- /dev/null
+++ b/app/javascript/flavours/glitch/components/error_boundary.js
@@ -0,0 +1,92 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { FormattedMessage } from 'react-intl';
+
+export default class ErrorBoundary extends React.PureComponent {
+
+  static propTypes = {
+    children: PropTypes.node,
+  };
+
+  state = {
+    hasError: false,
+    stackTrace: undefined,
+    componentStack: undefined,
+  }
+
+  componentDidCatch(error, info) {
+    this.setState({
+      hasError: true,
+      stackTrace: error.stack,
+      componentStack: info && info.componentStack,
+    });
+  }
+
+  handleReload(e) {
+    e.preventDefault();
+    window.location.reload();
+  }
+
+  render() {
+    const { hasError, stackTrace, componentStack } = this.state;
+
+    if (!hasError) return this.props.children;
+
+    let debugInfo = '';
+    if (stackTrace) {
+      debugInfo += 'Stack trace\n-----------\n\n```\n' + stackTrace.toString() + '\n```';
+    }
+    if (componentStack) {
+      if (debugInfo) {
+        debugInfo += '\n\n\n';
+      }
+      debugInfo += 'React component stack\n---------------------\n\n```\n' + componentStack.toString() + '\n```';
+    }
+
+    return (
+      <div tabIndex='-1'>
+        <div className='error-boundary'>
+          <h1><FormattedMessage id='web_app_crash.title' defaultMessage="We're sorry, but something went wrong with the Mastodon app." /></h1>
+          <p>
+            <FormattedMessage id='web_app_crash.content' defaultMessage='You could try any of the following:' />
+            <ul>
+              <li>
+                <FormattedMessage
+                  id='web_app_crash.report_issue'
+                  defaultMessage='Report a bug in the {issuetracker}'
+                  values={{ issuetracker: <a href='https://github.com/glitch-soc/mastodon/issues' rel='noopener' target='_blank'><FormattedMessage id='web_app_crash.issue_tracker' defaultMessage='issue tracker' /></a> }}
+                />
+                { debugInfo !== '' && (
+                  <details>
+                    <summary><FormattedMessage id='web_app_crash.debug_info' defaultMessage='Debug information' /></summary>
+                    <textarea
+                      className='web_app_crash-stacktrace'
+                      value={debugInfo}
+                      rows='10'
+                      readOnly
+                    />
+                  </details>
+                )}
+              </li>
+              <li>
+                <FormattedMessage
+                  id='web_app_crash.reload_page'
+                  defaultMessage='{reload} the current page'
+                  values={{ reload: <a href='#' onClick={this.handleReload}><FormattedMessage id='web_app_crash.reload' defaultMessage='Reload' /></a> }}
+                />
+              </li>
+              <li>
+                <FormattedMessage
+                  id='web_app_crash.change_your_settings'
+                  defaultMessage='Change your {settings}'
+                  values={{ settings: <a href='/settings/preferences'><FormattedMessage id='web_app_crash.settings' defaultMessage='settings' /></a> }}
+                />
+              </li>
+            </ul>
+          </p>
+        </div>
+      </div>
+    );
+  }
+
+}