From 72f16775e7d8232053dbb8831d4805cccd87924b Mon Sep 17 00:00:00 2001 From: Nishchay Date: Thu, 29 Mar 2018 14:56:55 +0530 Subject: [PATCH 1/5] Update new dependencies Add sentry config to index.js Add sentry to redux store using middleware Add sentry error reporting to api calls in httpFetch.js Add sentry error reporting in Home.jsx Create new 'lib/util.js' file to provide sentry error specific data --- package.json | 6 ++-- src/actions/index.js | 14 +++++---- src/components/Home.jsx | 65 +++++++++++++++++++++++----------------- src/index.js | 19 ++++++++---- src/lib/utils.js | 8 +++++ src/service/httpFetch.js | 2 +- 6 files changed, 73 insertions(+), 41 deletions(-) create mode 100644 src/lib/utils.js diff --git a/package.json b/package.json index 9d25539..db057e4 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,15 @@ "jest-localstorage-mock": "^2.2.0", "moment": "^2.21.0", "prop-types": "latest", + "raven-for-redux": "^1.3.0", + "raven-js": "^3.24.0", "react": "^16.2.0", "react-dom": "^16.2.0", "react-redux": "^5.0.7", "react-router-dom": "^4.2.2", "react-scripts": "1.1.1", "redux": "^3.7.2", + "redux-devtools-extension": "^2.13.2", "redux-immutable": "^4.0.0", "redux-logger": "^3.0.6", "redux-thunk": "^2.2.0" @@ -49,8 +52,7 @@ "eslint-config-airbnb": "^16.1.0", "eslint-plugin-import": "^2.9.0", "eslint-plugin-jsx-a11y": "^6.0.3", - "eslint-plugin-react": "^7.7.0", - "redux-devtools-extension": "^2.13.2" + "eslint-plugin-react": "^7.7.0" }, "eslintIgnore": [ "index.js", diff --git a/src/actions/index.js b/src/actions/index.js index 71c88ac..245ab66 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -1,4 +1,7 @@ +import * as Raven from 'raven-js'; + import { getAuthToken, getUserDetails } from '../service/httpFetch'; +import { sentryExtra } from '../lib/utils'; export const SIGNIN_REQUEST = 'SIGNIN_REQUEST'; export const SIGNED_IN = 'SIGNED_IN'; @@ -12,23 +15,22 @@ export function beginSignIn(authCode) { }; } - function success(token) { return { type: SIGNED_IN, token, }; } + return (dispatch) => { dispatch(start()); getAuthToken(authCode).then((res) => { - // console.log(res.data); const authToken = res.data.token; localStorage.setItem('auth-token', authToken); dispatch(success(authToken)); }).catch((err) => { - console.log(err); + Raven.captureException(err, sentryExtra('Error while fetching auth token')); }); }; } @@ -45,10 +47,10 @@ export function getUserInfo() { getUserDetails().then((res) => { // console.log(res.data); dispatch(success(res.data)); - }, (err) => { - console.error(err); }).catch((err) => { - console.error(err); + Raven.captureMessage('Error while fetching user Info', { + level: 'error', + }).captureException(err); }); }; } diff --git a/src/components/Home.jsx b/src/components/Home.jsx index d3977bd..84149f6 100644 --- a/src/components/Home.jsx +++ b/src/components/Home.jsx @@ -2,11 +2,14 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import PropTypes from 'prop-types'; +import * as Raven from 'raven-js'; + import { getUserInfo } from '../actions'; import Profile from './Profile'; import RepoList from './RepoList'; import { getFeeds, getRepos } from '../service/httpFetch'; import FeedList from './FeedsList'; +import { sentryExtra } from '../lib/utils'; class Home extends Component { constructor(props) { @@ -30,9 +33,9 @@ class Home extends Component { shouldComponentUpdate(nextProps, nextState) { return ( (nextState.fetchedFeeds !== this.state.fetchedFeeds) || - nextState.repoList !== this.state.repoList || - nextProps.token !== this.props.token || - nextProps.user !== this.props.user + nextState.repoList !== this.state.repoList || + nextProps.token !== this.props.token || + nextProps.user !== this.props.user ); } @@ -41,30 +44,38 @@ class Home extends Component { this.props.getInfo(); } if (nextProps.user - && this.state.fetchedFeeds === false - && nextState.fetchedFeeds === false) { + && this.state.fetchedFeeds === false + && nextState.fetchedFeeds === false) { this.getUserFeeds(nextProps.user.login); } } - getUserRepos() { getRepos(this.state.username).then((res) => { this.setState({ repoList: res.data, }); + }).catch((err) => { + Raven.captureException(err, sentryExtra('Error during fetching user repos')); }); } getUserFeeds(login) { - getFeeds(login).then((res) => { + getFeeds(`${login}`).then((res) => { this.setState({ feedList: res.data, fetchedFeeds: true, }); + }).catch((err) => { + Raven.captureException(err, sentryExtra('Error while fetching user feeds')); }); } + // eslint-disable-next-line class-methods-use-this + componentDidCatch(error, errorInfo) { + Raven.captureException(error, { extra: errorInfo }); + } + handleChange(e) { this.setState({ username: e.target.value, @@ -86,28 +97,28 @@ class Home extends Component {
{ - data && -
-
- + data && +
+
+ Enter Username - -
- -
+ + -
- } + +
+ } diff --git a/src/index.js b/src/index.js index 18e22da..ab45279 100644 --- a/src/index.js +++ b/src/index.js @@ -1,17 +1,26 @@ +/* eslint-disable react/jsx-filename-extension */ import React from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; -import App from './App'; -import registerServiceWorker from './registerServiceWorker'; +import Raven from 'raven-js'; // Or, you might already have this as `window.Raven`. import { BrowserRouter as Router } from 'react-router-dom'; -import rootReducer from './reducers'; import { applyMiddleware, createStore } from 'redux'; import { logger } from 'redux-logger'; import thunk from 'redux-thunk'; import { Provider } from 'react-redux'; import { composeWithDevTools } from 'redux-devtools-extension'; +import createRavenMiddleware from 'raven-for-redux'; + +import './index.css'; +import App from './App'; +import rootReducer from './reducers'; +import registerServiceWorker from './registerServiceWorker'; + +Raven.config('https://ff415653dd0b41bd951cf8e3e19cf703@sentry.io/768696').install(); -const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk, logger))); +const store = createStore(rootReducer, composeWithDevTools(applyMiddleware( + thunk, logger, + createRavenMiddleware(Raven), +))); ReactDOM.render( diff --git a/src/lib/utils.js b/src/lib/utils.js new file mode 100644 index 0000000..b604a13 --- /dev/null +++ b/src/lib/utils.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/prefer-default-export +export function sentryExtra(txt) { + return { + extra: { + error_origin: txt, + }, + }; +} diff --git a/src/service/httpFetch.js b/src/service/httpFetch.js index b87fff4..462050e 100644 --- a/src/service/httpFetch.js +++ b/src/service/httpFetch.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { ROOT_URL, TOKEN_URL } from '../lib/constants'; +import {ROOT_URL, TOKEN_URL} from '../lib/constants'; const getDefaultConfig = () => ({ // use a function so it doesn't cache the config info From a638eb73b976ef56f761e052010a1ae31eb87b5d Mon Sep 17 00:00:00 2001 From: Nishchay Date: Thu, 29 Mar 2018 14:58:01 +0530 Subject: [PATCH 2/5] Fix lint error in httpFetch.js --- src/service/httpFetch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/httpFetch.js b/src/service/httpFetch.js index 462050e..b87fff4 100644 --- a/src/service/httpFetch.js +++ b/src/service/httpFetch.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import {ROOT_URL, TOKEN_URL} from '../lib/constants'; +import { ROOT_URL, TOKEN_URL } from '../lib/constants'; const getDefaultConfig = () => ({ // use a function so it doesn't cache the config info From 0ce411b4eb4fdec2ece52308c99cfa7c0d37bf01 Mon Sep 17 00:00:00 2001 From: Nishchay Date: Thu, 29 Mar 2018 15:13:02 +0530 Subject: [PATCH 3/5] Add sentryExtra method in a missed action --- src/actions/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/actions/index.js b/src/actions/index.js index 245ab66..1614161 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -48,9 +48,7 @@ export function getUserInfo() { // console.log(res.data); dispatch(success(res.data)); }).catch((err) => { - Raven.captureMessage('Error while fetching user Info', { - level: 'error', - }).captureException(err); + Raven.captureException(err, sentryExtra('Error while fetching user Info')); }); }; } From 9680af77157d7bd983dba06b5fe19b312b64ce39 Mon Sep 17 00:00:00 2001 From: N Kaushik Date: Mon, 2 Apr 2018 15:26:02 +0530 Subject: [PATCH 4/5] Add error message display on error --- src/components/Home.jsx | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/components/Home.jsx b/src/components/Home.jsx index 84149f6..650e1ee 100644 --- a/src/components/Home.jsx +++ b/src/components/Home.jsx @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; @@ -10,6 +11,7 @@ import RepoList from './RepoList'; import { getFeeds, getRepos } from '../service/httpFetch'; import FeedList from './FeedsList'; import { sentryExtra } from '../lib/utils'; +import { USER_FEEDS_ERROR, USER_REPO_ERROR } from '../lib/constants'; class Home extends Component { constructor(props) { @@ -19,6 +21,7 @@ class Home extends Component { repoList: [], feedList: [], fetchedFeeds: false, + isError: false, }; this.getUserRepos = this.getUserRepos.bind(this); this.handleChange = this.handleChange.bind(this); @@ -56,7 +59,10 @@ class Home extends Component { repoList: res.data, }); }).catch((err) => { - Raven.captureException(err, sentryExtra('Error during fetching user repos')); + // Raven.captureException(err, sentryExtra('Error during fetching user repos')); + this.setState({ + isError: USER_REPO_ERROR, + }); }); } @@ -65,9 +71,13 @@ class Home extends Component { this.setState({ feedList: res.data, fetchedFeeds: true, + // eslint-disable-next-line no-unused-vars }); }).catch((err) => { - Raven.captureException(err, sentryExtra('Error while fetching user feeds')); + // Raven.captureException(err, sentryExtra('Error while fetching user feeds')); + this.setState({ + isError: USER_FEEDS_ERROR, + }); }); } @@ -86,6 +96,9 @@ class Home extends Component { render() { const data = this.props.user; const { repoList, feedList } = this.state; + const feedError = this.state.isError === USER_FEEDS_ERROR; + const repoError = this.state.isError === USER_REPO_ERROR; + return (
@@ -93,7 +106,10 @@ class Home extends Component { {data && }
+ { feedError &&

Please try again.

Can not fetch feeds.

} + +
{ @@ -120,6 +136,8 @@ class Home extends Component {
} + { repoError &&

Please try again.

Can not repository list.

} +
From c7aee333feece867e3ddc3439e172771d8ed7408 Mon Sep 17 00:00:00 2001 From: N Kaushik Date: Mon, 2 Apr 2018 15:28:29 +0530 Subject: [PATCH 5/5] Add new error constants --- src/lib/constants.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/constants.js b/src/lib/constants.js index 8a4cc6b..0c55c20 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -10,3 +10,6 @@ export const AUTH_URL = `https://github.com/login/oauth/authorize?client_id=${CL export const TOKEN_URL = 'http://localhost:9999/authenticate'; export const USER_DETAIL_URL = 'https://api.github.com/user'; + +export const USER_FEEDS_ERROR = 1; +export const USER_REPO_ERROR = 2;