diff --git a/src/analytics.js b/src/analytics.js
new file mode 100644
index 0000000..245cdde
--- /dev/null
+++ b/src/analytics.js
@@ -0,0 +1,26 @@
+const LOG_ENDPOINT = ''
+
+export function raiseError(error) {
+ return reportError(error)
+}
+
+export function withErrorLog(func) {
+ return function () {
+ try {
+ func()
+ } catch (error) {
+ raiseError(error)
+ }
+ }
+}
+
+function encodeParams(params) {
+ return Object.keys(params).map(key => `${key}=${encodeURIComponent(JSON.stringify(params[key]))}`).join('&')
+}
+
+function reportError(error) {
+ return fetch(`${LOG_ENDPOINT}?${encodeParams({
+ error: error && error.message || error,
+ path: window.location.href,
+ })}`)
+}
diff --git a/src/components/Gitako.js b/src/components/Gitako.js
index 832d5cb..9a057bc 100644
--- a/src/components/Gitako.js
+++ b/src/components/Gitako.js
@@ -4,8 +4,15 @@ import SideBar from './SideBar'
import { Gitako as GitakoCore } from '../driver/core'
import connect from '../driver/connect'
+import { raiseError } from '../analytics'
+
@connect(GitakoCore)
export default class Gitako extends React.PureComponent {
+
+ componentDidCatch(error) {
+ raiseError(error)
+ }
+
render() {
return (
diff --git a/src/driver/connect.js b/src/driver/connect.js
index 0d11a62..49a7ebd 100644
--- a/src/driver/connect.js
+++ b/src/driver/connect.js
@@ -1,18 +1,19 @@
import React from 'react'
+import { withErrorLog } from "../analytics"
+
+function async(func) {
+ return new Promise(resolve => setTimeout(() => resolve(func())))
+}
+
+function sync(func) {
+ return func()
+}
+
function link(instance, sources) {
- const wrappedMethods = {/* sources[key] -> wrappedMethods.method */}
+ const wrappedMethods = {/* [keyof sources] -> wrappedMethods.method */}
const map = new Map(/* sources.creator -> wrappedMethods.method */)
- function dispatch(...args) {
- if (Object.values(sources).includes(args[0])) {
- map.get(args[0])(...args.slice(1))
- } else {
- setTimeout(
- instance.setState.bind(instance, ...args),
- )
- }
- }
Object.entries(sources).forEach(([key, createMethod]) => {
const method = createMethod(dispatch)
@@ -20,6 +21,15 @@ function link(instance, sources) {
map.set(createMethod, method)
})
+ function dispatch(...args) {
+ const isFromSource = Object.values(sources).includes(args[0])
+ if (isFromSource) {
+ sync(withErrorLog(() => map.get(args[0])(...args.slice(1))))
+ } else {
+ async(() => instance.setState(...args))
+ }
+ }
+
return wrappedMethods
}
@@ -32,9 +42,7 @@ export default function connect(mapping) {
boundCore = link(this, mapping)
render() {
- return (
-
- )
+ return
}
}
}
diff --git a/src/driver/core/SideBar.js b/src/driver/core/SideBar.js
index 139f914..df1ad1a 100644
--- a/src/driver/core/SideBar.js
+++ b/src/driver/core/SideBar.js
@@ -36,7 +36,6 @@ const init = dispatch => async () => {
})
dispatch(setShouldShow, errorDueToAuth)
} else {
- console.error(err)
dispatch(setShouldShow, false)
}
}