diff --git a/package.json b/package.json index b3b47a9..2f43ded 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "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", @@ -52,8 +54,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..1614161 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,8 @@ export function getUserInfo() { getUserDetails().then((res) => { // console.log(res.data); dispatch(success(res.data)); - }, (err) => { - console.error(err); }).catch((err) => { - console.error(err); + Raven.captureException(err, sentryExtra('Error while fetching user Info')); }); }; } diff --git a/src/components/Home.jsx b/src/components/Home.jsx index d3977bd..650e1ee 100644 --- a/src/components/Home.jsx +++ b/src/components/Home.jsx @@ -1,12 +1,17 @@ +/* eslint-disable no-unused-vars */ 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'; +import { USER_FEEDS_ERROR, USER_REPO_ERROR } from '../lib/constants'; class Home extends Component { constructor(props) { @@ -16,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); @@ -30,9 +36,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 +47,45 @@ 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')); + this.setState({ + isError: USER_REPO_ERROR, + }); }); } getUserFeeds(login) { - getFeeds(login).then((res) => { + getFeeds(`${login}`).then((res) => { 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')); + this.setState({ + isError: USER_FEEDS_ERROR, }); }); } + // eslint-disable-next-line class-methods-use-this + componentDidCatch(error, errorInfo) { + Raven.captureException(error, { extra: errorInfo }); + } + handleChange(e) { this.setState({ username: e.target.value, @@ -75,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 (
@@ -82,32 +106,37 @@ class Home extends Component { {data && }
+ { feedError &&

Please try again.

Can not fetch feeds.

} + +
{ - data && -
-
- + data && +
+
+ Enter Username - -
- -
+ + -
- } + +
+ } + + { repoError &&

Please try again.

Can not repository list.

}
diff --git a/src/index.js b/src/index.js index 7e9598d..060be0e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,18 +1,25 @@ /* eslint-disable react/jsx-filename-extension */ import React from 'react'; import ReactDOM from 'react-dom'; +import Raven from 'raven-js'; // Or, you might already have this as `window.Raven`. +import { BrowserRouter as Router } from 'react-router-dom'; 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 { BrowserRouter as Router } from 'react-router-dom'; +import createRavenMiddleware from 'raven-for-redux'; import './index.css'; import App from './App'; -import registerServiceWorker from './registerServiceWorker'; 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/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; 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, + }, + }; +}