From f707b393fcd5d24752e24f71aafcd2418d4cb364 Mon Sep 17 00:00:00 2001 From: EnixCoda Date: Sun, 5 Aug 2018 16:32:31 +0800 Subject: [PATCH] feat: catch error --- src/analytics.js | 26 ++++++++++++++++++++++++++ src/components/Gitako.js | 7 +++++++ src/driver/connect.js | 34 +++++++++++++++++++++------------- src/driver/core/SideBar.js | 1 - 4 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 src/analytics.js 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) } }