Skip to content

Commit

Permalink
Merge e2e21ac into 55526d8
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed Mar 12, 2018
2 parents 55526d8 + e2e21ac commit ee12c74
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -30,6 +30,7 @@
* Upgrade to Webpack 4 @sneridagh
* Renew login token when almost expired @robgietema
* Added actions reducers @robgietema
* Add error reporting with Sentry support on client (default ErrorBoundary), server and Redux middleware @sneridagh

## 0.4.0 (2017-05-03)

Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -196,6 +196,8 @@
"pretty-error": "2.1.1",
"promise-file-reader": "1.0.2",
"prop-types": "15.6.1",
"raven": "2.4.2",
"raven-js": "3.23.1",
"react": "16.2.0",
"react-cookie": "1.0.5",
"react-dnd": "2.5.4",
Expand Down
50 changes: 48 additions & 2 deletions src/components/theme/App/App.jsx
Expand Up @@ -10,6 +10,9 @@ import { asyncConnect } from 'redux-connect';
import Helmet from 'react-helmet';
import { Segment, Container } from 'semantic-ui-react';
import { bindActionCreators } from 'redux';
import Raven from 'raven-js';

import Error from '../../../error';

import {
Breadcrumbs,
Expand Down Expand Up @@ -59,15 +62,51 @@ export class AppComponent extends Component {
toolbar: null,
};

state = {
hasError: false,
error: null,
errorInfo: null,
};

/**
* ComponentDidMount
* @method ComponentDidMount
* @param {string} error The error
* @param {string} info The info
* @returns {undefined}
*/
componentDidMount() {
if (__CLIENT__ && process.env.SENTRY_DSN) {
Raven.config(process.env.SENTRY_DSN).install();
}
}

/**
* @method componentWillReceiveProps
* @param {Object} nextProps Next properties
* @returns {undefined}
*/
componentWillReceiveProps(nextProps) {
// We purge messages on each route change
if (nextProps.pathname !== this.props.pathname) {
this.props.purgeMessages();

if (this.state.hasError) {
this.setState({ hasError: false });
}
}
}

/**
* ComponentDidCatch
* @method ComponentDidCatch
* @param {string} error The error
* @param {string} info The info
* @returns {undefined}
*/
componentDidCatch(error, info) {
this.setState({ hasError: true, error, errorInfo: info });
if (__CLIENT__ && process.env.SENTRY_DSN) {
Raven.captureException(error, { extra: info });
}
}

Expand All @@ -94,7 +133,14 @@ export class AppComponent extends Component {
<Segment basic className="content-area">
<Container as="main">
<Messages />
{this.props.main}
{this.state.hasError ? (
<Error
message={this.state.error.message}
stackTrace={this.state.errorInfo.componentStack}
/>
) : (
this.props.main
)}
</Container>
</Segment>
<Footer />
Expand Down
35 changes: 31 additions & 4 deletions src/error.jsx
Expand Up @@ -11,15 +11,42 @@ import PropTypes from 'prop-types';
* @function Error
* @returns {string} Markup of the error page.
*/
const Error = ({ message }) => (
<div>
<span>Something went wrong:&nbsp;</span>
<span>{message}</span>
const Error = ({ message, stackTrace }) => (
<div
style={{
fontFamily: __SERVER__ ? 'Helvetica, sans-serif' : null,
fontSize: __SERVER__ ? '20px' : '16px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
height: __SERVER__ ? '100vh' : null,
}}
>
{/* TODO: Replace inline styling with a CSS class, inline style only for __SERVER__ */}
<h2>Sorry, something went wrong with your request&nbsp;</h2>
<strong style={{ color: 'red' }}>{message}</strong>
<pre>{stackTrace}</pre>
<span style={{ textAlign: 'center' }}>
<p>
{/* eslint-disable-next-line */}
<a href="javascript: history.back()">Navigate back</a>
</p>
<p>
<a href="/">return to the site root</a>
</p>
<p>or try a different page.</p>
</span>
</div>
);

Error.propTypes = {
message: PropTypes.string.isRequired,
stackTrace: PropTypes.string,
};

Error.defaultProps = {
stackTrace: null,
};

export default Error;
19 changes: 19 additions & 0 deletions src/middleware/crashReporter.js
@@ -0,0 +1,19 @@
import Raven from 'raven-js';

const crashReporter = store => next => action => {
try {
return next(action);
} catch (error) {
if (__CLIENT__ && process.env.SENTRY_DSN) {
Raven.captureException(error, {
extra: {
action,
state: store.getState(),
},
});
}
throw error;
}
};

export default crashReporter;
1 change: 1 addition & 0 deletions src/middleware/index.js
Expand Up @@ -5,3 +5,4 @@
*/

export api from './api';
export crashReporter from './crashReporter';
11 changes: 11 additions & 0 deletions src/server.jsx
Expand Up @@ -15,6 +15,7 @@ import cookie, { plugToRequest } from 'react-cookie';
import { urlencoded } from 'body-parser';
import locale from 'locale';
import { keys } from 'lodash';
import Raven from 'raven';

import nlLocale from '../dist/locales/nl.json';
import deLocale from '../dist/locales/de.json';
Expand Down Expand Up @@ -42,6 +43,10 @@ export default parameters => {
const io = new SocketIO(server);
const staticPath = __dirname;

if (process.env.SENTRY_DSN) {
Raven.config(process.env.SENTRY_DSN).install();
}

io.on('connection', () => {
debug.info('user connected');
});
Expand Down Expand Up @@ -119,6 +124,12 @@ export default parameters => {
})
.catch(error => {
const errorPage = <ErrorPage message={error.message} />;

if (process.env.SENTRY_DSN) {
Raven.captureException(error.message, {
extra: JSON.stringify(error),
});
}
res.set({
'Cache-Control': 'public, max-age=60, no-transform',
});
Expand Down
11 changes: 9 additions & 2 deletions src/store.js
Expand Up @@ -3,7 +3,7 @@ import { createStore, compose, applyMiddleware } from 'redux';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';

import { api } from './middleware';
import { api, crashReporter } from './middleware';
import reducer from './reducers';

/**
Expand Down Expand Up @@ -42,7 +42,14 @@ export default function configureStore(
apiHelper,
) {
const middlewares = addToMiddleWare(
[applyMiddleware(routerMiddleware(history), thunk, api(apiHelper))],
[
applyMiddleware(
routerMiddleware(history),
crashReporter,
thunk,
api(apiHelper),
),
],
logger,
);

Expand Down
6 changes: 6 additions & 0 deletions webpack/webpack.config.client.prod.js
Expand Up @@ -12,6 +12,12 @@ configuration.plugins.push(
HOST: process.env.HOST && process.env.HOST,
PORT: process.env.PORT,
API_PATH: process.env.API_PATH && JSON.stringify(process.env.API_PATH),
// SENTRY_DSN - Enable Sentry error reporting
// You need to pass the (public) Sentry DSN for JS Raven to work
// Uncomment the next lines and replace the value with the DSN for your Sentry project
// SENTRY_DSN: JSON.stringify(
// '<your_public_SentryDSN>',
// ),
},
__CLIENT__: true,
__SERVER__: false,
Expand Down
6 changes: 6 additions & 0 deletions webpack/webpack.config.server.prod.js
Expand Up @@ -11,6 +11,12 @@ configuration.plugins.push(
HOST: process.env.HOST && process.env.HOST,
PORT: process.env.PORT,
API_PATH: process.env.API_PATH && JSON.stringify(process.env.API_PATH),
// SENTRY_DSN - Enable Sentry error reporting
// You need the full Sentry DSN (private) configured here for Node Raven to work
// Uncomment the next lines and replace the value with the private DSN for your Sentry project
// SENTRY_DSN: JSON.stringify(
// '<your_private_SentryDSN>',
// ),
},
__CLIENT__: false,
__SERVER__: true,
Expand Down
48 changes: 43 additions & 5 deletions yarn.lock
Expand Up @@ -2151,6 +2151,10 @@ chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"

charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"

check-error@^1.0.1, check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
Expand Down Expand Up @@ -2865,6 +2869,10 @@ cross-spawn@^6.0.5:
shebang-command "^1.2.0"
which "^1.2.9"

crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"

cryptiles@0.2.x:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-0.2.2.tgz#ed91ff1f17ad13d3748288594f8a48a0d26f325c"
Expand Down Expand Up @@ -5947,7 +5955,7 @@ is-boolean-object@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"

is-buffer@^1.1.4, is-buffer@^1.1.5:
is-buffer@^1.1.4, is-buffer@^1.1.5, is-buffer@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"

Expand Down Expand Up @@ -7713,6 +7721,14 @@ md5.js@^1.3.4:
hash-base "^3.0.0"
inherits "^2.0.1"

md5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
dependencies:
charenc "~0.0.1"
crypt "~0.0.1"
is-buffer "~1.1.1"

mdast-util-compact@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz#cdb5f84e2b6a2d3114df33bd05d9cb32e3c4083a"
Expand Down Expand Up @@ -9620,6 +9636,20 @@ range-parser@^1.0.3, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"

raven-js@3.23.1:
version "3.23.1"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.23.1.tgz#34a5d7b5b3dd626a3d59e7a264e1d19a4c799cdb"

raven@2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/raven/-/raven-2.4.2.tgz#0129e2adc30788646fd530b67d08a8ce25d4f6dc"
dependencies:
cookie "0.3.1"
md5 "^2.2.1"
stack-trace "0.0.9"
timed-out "4.0.1"
uuid "3.0.0"

raw-body@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89"
Expand Down Expand Up @@ -11316,6 +11346,10 @@ ssri@^5.2.4:
dependencies:
safe-buffer "^5.1.1"

stack-trace@0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"

stack-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620"
Expand Down Expand Up @@ -11924,14 +11958,14 @@ time-stamp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357"

timed-out@4.0.1, timed-out@^4.0.0, timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"

timed-out@^3.0.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-3.1.3.tgz#95860bfcc5c76c277f8f8326fd0f5b2e20eba217"

timed-out@^4.0.0, timed-out@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"

timekeeper@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/timekeeper/-/timekeeper-2.0.0.tgz#eaf7a0dcfdc95d4658b9cc3d21107206cc4e2eed"
Expand Down Expand Up @@ -12493,6 +12527,10 @@ utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"

uuid@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728"

uuid@3.2.1, uuid@^3.0.1, uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
Expand Down

0 comments on commit ee12c74

Please sign in to comment.