diff --git a/package-lock.json b/package-lock.json
index b43b5231c..86a9ba68e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24758,6 +24758,21 @@
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
},
+ "sourcemapped-stacktrace": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/sourcemapped-stacktrace/-/sourcemapped-stacktrace-1.1.11.tgz",
+ "integrity": "sha512-O0pcWjJqzQFVsisPlPXuNawJHHg9N9UgpJ/aDmvi9+vnS3x1C0NhwkVFzzZ1VN0Xo+bekyweoqYvBw5ZBKiNnQ==",
+ "requires": {
+ "source-map": "0.5.6"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+ "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
+ }
+ }
+ },
"space-separated-tokens": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz",
diff --git a/package.json b/package.json
index 0225b7851..80c5095f7 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"react-scroll": "^1.7.10",
"react-sound": "^1.2.0",
"rimble-ui": "0.4.2",
+ "sourcemapped-stacktrace": "^1.1.11",
"styled-components": "^4.1.3",
"web3": "1.0.0-beta.36",
"ya-bbcode": "^1.0.9"
diff --git a/src/App.js b/src/App.js
index f4b4eab5b..404853780 100644
--- a/src/App.js
+++ b/src/App.js
@@ -867,6 +867,7 @@ class App extends Component {
const { voteStartTime, voteEndTime, trashBox } = this.state;
const web3Props = { plasma: xdaiweb3, web3, account, metaAccount };
+
return (
<>
{account ? (
diff --git a/src/components/Advanced.js b/src/components/Advanced.js
index d586732df..e8ec2ec93 100644
--- a/src/components/Advanced.js
+++ b/src/components/Advanced.js
@@ -231,7 +231,7 @@ export default class Advanced extends React.Component {
{privateKey &&
-
this.props.history.push("/burn")}>
+ this.props.history.push("/burn")}>
{i18n.t('burn')}
diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.js
new file mode 100644
index 000000000..af0eb0890
--- /dev/null
+++ b/src/components/ErrorBoundary.js
@@ -0,0 +1,82 @@
+// Nice stuff here: https://reactjs.org/blog/2017/07/26/error-handling-in-react-16.html
+// Code taken from Dan Abramov's pen https://codepen.io/gaearon/pen/wqvxGa
+
+import React from "react";
+import { Box, Card, Heading, Flex, Button } from "rimble-ui";
+import styled from "styled-components";
+import { CopyToClipboard } from "react-copy-to-clipboard";
+import { mapStackTrace } from "sourcemapped-stacktrace";
+
+const Container = styled(Card)`
+ margin: 0;
+`;
+
+const Details = styled(Box).attrs(() => ({
+ mt: 0,
+ mb: 4,
+ fontSize: 2
+}))``;
+
+const Pre = styled.pre`
+ font-family: monospace;
+ font-size: 10px;
+`;
+
+export default class ErrorBoundary extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = { error: null, errorInfo: null };
+ }
+
+ componentDidCatch(error, errorInfo) {
+ this.setState({ broken: true });
+
+ mapStackTrace(error.stack, stack => {
+ const message = [
+ error.toString(),
+ ...stack,
+ "---",
+ error.toString(),
+ errorInfo.componentStack
+ ].join("\n");
+ this.setState({ message });
+ });
+ }
+
+ render() {
+ const { broken, message, copied } = this.state;
+
+ if (broken) {
+ return (
+
+ Something went wrong 😢
+
+ Please let us know about this error. If you did it already, reload
+ the page, thanks!
+
+
+ {message ? (
+ <>
+
+
+ {message}
+
+
+
+ this.setState({ copied: true })}
+ >
+
+
+ {copied && Copied!
}
+ >
+ ) : (
+ Loading details, wait... ⌛
+ )}
+
+ );
+ }
+ return this.props.children;
+ }
+}
diff --git a/src/index.js b/src/index.js
index 2e78ad184..1f164e388 100644
--- a/src/index.js
+++ b/src/index.js
@@ -7,6 +7,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import i18n from "./i18n";
import { I18nextProvider } from "react-i18next";
import { ThemeProvider } from "rimble-ui";
+import ErrorBoundary from "./components/ErrorBoundary";
import theme from "./theme";
@@ -14,7 +15,9 @@ ReactDOM.render(
-
+
+
+
,