diff --git a/package.json b/package.json
index fd86623..6297cad 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"dependencies": {
"@babel/polyfill": "^7.2.3",
"@babel/runtime": "^7.1.5",
+ "@sentry/browser": "^4.4.2",
"chart.js": "^2.7.3",
"classnames": "^2.2.6",
"history": "^4.7.2",
diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.js
new file mode 100644
index 0000000..a44ca92
--- /dev/null
+++ b/src/components/ErrorBoundary.js
@@ -0,0 +1,53 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { getSentry } from '../misc/sentry';
+
+// XXX this is no Hook equivalents for componentDidCatch
+// we have to use class for now
+
+class ErrorBoundary extends Component {
+ static propTypes = {
+ children: PropTypes.node
+ };
+
+ state = { error: null };
+
+ loadSentry = async () => {
+ if (this.sentry) return this.sentry;
+ const x = await getSentry();
+ this.sentry = x;
+ return this.sentry;
+ };
+
+ componentDidMount() {
+ this.loadSentry();
+ }
+
+ componentDidCatch(error, errorInfo) {
+ this.setState({ error });
+ this.loadSentry().then(Sentry => {
+ Sentry.withScope(scope => {
+ Object.keys(errorInfo).forEach(key => {
+ scope.setExtra(key, errorInfo[key]);
+ });
+ Sentry.captureException(error);
+ });
+ });
+ }
+
+ showReportDialog = () => {
+ this.loadSentry().then(Sentry => Sentry.showReportDialog());
+ };
+
+ render() {
+ if (this.state.error) {
+ //render fallback UI
+ return Report feedback;
+ } else {
+ //when there's not an error, render children untouched
+ return this.props.children;
+ }
+ }
+}
+
+export default ErrorBoundary;
diff --git a/src/components/Root.js b/src/components/Root.js
index a5f56e7..dc96e22 100644
--- a/src/components/Root.js
+++ b/src/components/Root.js
@@ -4,6 +4,7 @@ import { HashRouter as Router, Route } from 'react-router-dom';
// import { hot } from 'react-hot-loader';
// import createHistory from 'history/createHashHistory';
// import createHistory from 'history/createBrowserHistory';
+import ErrorBoundary from 'c/ErrorBoundary';
import SideBar from 'c/SideBar';
import Home from 'c/Home';
import Logs from 'c/Logs';
@@ -23,21 +24,23 @@ import s0 from './Root.module.scss';
window.store = store;
const Root = () => (
-
-
-
-
-
} />
-
-
} />
- } />
- } />
- } />
- } />
+
+
+
+
+
+
} />
+
+
} />
+ } />
+ } />
+ } />
+ } />
+
-
-
-
+
+
+
);
//
//
diff --git a/src/misc/sentry.js b/src/misc/sentry.js
new file mode 100644
index 0000000..435c41a
--- /dev/null
+++ b/src/misc/sentry.js
@@ -0,0 +1,9 @@
+const dsn = 'https://7068a15928ae45cf884dd8398fe8649c@sentry.io/1359284';
+let Sentry;
+export async function getSentry() {
+ if (Sentry) return Sentry;
+ const s = await import('@sentry/browser');
+ s.init({ dsn });
+ Sentry = s;
+ return Sentry;
+}
diff --git a/yarn.lock b/yarn.lock
index ce87063..1399f2b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -831,6 +831,58 @@
dependencies:
any-observable "^0.3.0"
+"@sentry/browser@^4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-4.4.2.tgz#8d361778962ef8ab1540e4ebbf64d485903abdf1"
+ integrity sha512-km5p3hPz+aoY4UiEvYxAdRJAbIK30urZSuMs/3zAUVe+8Zij0IHjHmdi9JtrMqpn+rAcWCxtRmFSYlkiKjdSUg==
+ dependencies:
+ "@sentry/core" "4.4.2"
+ "@sentry/types" "4.4.2"
+ "@sentry/utils" "4.4.2"
+ tslib "^1.9.3"
+
+"@sentry/core@4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-4.4.2.tgz#562526bc634c087f04bbca68b09cedc4b41cc64d"
+ integrity sha512-hJyAodTCf4sZfVdf41Rtuzj4EsyzYq5rdMZ+zc2Vinwdf8D0/brHe91fHeO0CKXEb2P0wJsrjwMidG/ccq/M8A==
+ dependencies:
+ "@sentry/hub" "4.4.2"
+ "@sentry/minimal" "4.4.2"
+ "@sentry/types" "4.4.2"
+ "@sentry/utils" "4.4.2"
+ tslib "^1.9.3"
+
+"@sentry/hub@4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-4.4.2.tgz#1399556fda06fb83c4f186c4aa842725f520159c"
+ integrity sha512-oe9ytXkTWyD+QmOpVzHAqTbRV4Hc0ee2Nt6HvrDtRmlXzQxfvTWG2F8KYT6w8kzqg5klnuRpnsmgTTV3KuNBVQ==
+ dependencies:
+ "@sentry/types" "4.4.2"
+ "@sentry/utils" "4.4.2"
+ tslib "^1.9.3"
+
+"@sentry/minimal@4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-4.4.2.tgz#13fffc6b17a2401b6a79947838a637626ab80b10"
+ integrity sha512-GEZZiNvVgqFAESZhAe3vjwTInn13lI2bSI3ItQN4RUWKL/W4n/fwVoDJbkb1U8aWxanuMnRDEpKwyQv6zYTZfw==
+ dependencies:
+ "@sentry/hub" "4.4.2"
+ "@sentry/types" "4.4.2"
+ tslib "^1.9.3"
+
+"@sentry/types@4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-4.4.2.tgz#f38dd3bc671cd2f5983a85553aebeac9c2286b17"
+ integrity sha512-QyQd6PKKIyjJgaq/RQjsxPJEWbXcuiWZ9RvSnhBjS5jj53HEzkM1qkbAFqlYHJ1DTJJ1EuOM4+aTmGzHe93zuA==
+
+"@sentry/utils@4.4.2":
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-4.4.2.tgz#e05a47e135ecef29e63a996f59aee8c8f792c222"
+ integrity sha512-j/Ad8G1abHlJdD2q7aWWbSOSeWB5M5v1R1VKL8YPlwEbSvvmEQWePhBKFI0qlnKd2ObdUQsj86pHEXJRSFNfCw==
+ dependencies:
+ "@sentry/types" "4.4.2"
+ tslib "^1.9.3"
+
"@types/q@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.1.tgz#48fd98c1561fe718b61733daed46ff115b496e18"
@@ -7731,7 +7783,7 @@ tryer@^1.0.0:
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==
-tslib@^1.9.0:
+tslib@^1.9.0, tslib@^1.9.3:
version "1.9.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==