diff --git a/config/template.env.js b/config/template.env.js index 53ff779..69e7104 100644 --- a/config/template.env.js +++ b/config/template.env.js @@ -1,4 +1,5 @@ module.exports = { apiHost: 'https://dev.account.ely.by', - ga: {id: 'UA-XXXXX-Y'} + ga: {id: 'UA-XXXXX-Y'}, + sentryCdn: 'https://@sentry.io/' }; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 98a7eaa..c7184cd 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -3498,8 +3498,7 @@ "json-stringify-safe": { "version": "5.0.1", "from": "json-stringify-safe@>=5.0.1 <5.1.0", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "dev": true + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" }, "json3": { "version": "3.2.6", @@ -5108,6 +5107,11 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", "dev": true }, + "raven-js": { + "version": "3.8.1", + "from": "raven-js@latest", + "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.8.1.tgz" + }, "raw-body": { "version": "2.1.7", "from": "raw-body@>=2.1.7 <2.2.0", diff --git a/package.json b/package.json index 5535e2e..3b3cc2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ely-by-account", - "version": "1.0.0", + "version": "1.1.3-dev", "description": "", "main": "index.js", "author": "ErickSkrauch ", @@ -27,6 +27,7 @@ "intl-format-cache": "^2.0.4", "intl-messageformat": "^1.1.0", "promise.prototype.finally": "^2.0.0", + "raven-js": "^3.8.1", "react": "^15.0.0", "react-addons-css-transition-group": "^15.1.0", "react-dom": "^15.0.0", diff --git a/src/components/accounts/actions.js b/src/components/accounts/actions.js index 0d69005..8d955a3 100644 --- a/src/components/accounts/actions.js +++ b/src/components/accounts/actions.js @@ -2,6 +2,7 @@ import authentication from 'services/api/authentication'; import accounts from 'services/api/accounts'; import { updateUser, logout } from 'components/user/actions'; import { setLocale } from 'components/i18n/actions'; +import logger from 'services/logger'; /** * @typedef {object} Account @@ -31,7 +32,10 @@ export function authenticate({token, refreshToken}) { .then(({token, refreshToken}) => accounts.current({token}) .then((user) => ({ - user, + user: { + isGuest: false, + ...user + }, account: { id: user.id, username: user.username, @@ -44,10 +48,10 @@ export function authenticate({token, refreshToken}) { .then(({user, account}) => { dispatch(add(account)); dispatch(activate(account)); - dispatch(updateUser({ - isGuest: false, - ...user - })); + dispatch(updateUser(user)); + + // TODO: probably should be moved from here, because it is a side effect + logger.setUser(user); if (!account.refreshToken) { // mark user as stranger (user does not want us to remember his account) diff --git a/src/index.js b/src/index.js index 2f08abb..9b2232e 100644 --- a/src/index.js +++ b/src/index.js @@ -14,6 +14,11 @@ import routesFactory from 'routes'; import storeFactory from 'storeFactory'; import bsodFactory from 'components/ui/bsod/factory'; import loader from 'services/loader'; +import logger from 'services/logger'; + +logger.init({ + sentryCdn: window.sentryCdn +}); const store = storeFactory(); diff --git a/src/services/logger.js b/src/services/logger.js new file mode 100644 index 0000000..1fe7547 --- /dev/null +++ b/src/services/logger.js @@ -0,0 +1,62 @@ +import Raven from 'raven-js'; + +const isTest = process.env.__TEST__; // eslint-disable-line + +const logger = { + init({sentryCdn}) { + if (sentryCdn) { + Raven.config(sentryCdn, { + logger: 'accounts-js-app', + level: 'info', + environment: process.env.NODE_ENV, // eslint-disable-line + release: process.env.__VERSION__, // eslint-disable-line + shouldSendCallback: () => !isTest, + dataCallback: (data) => { + if (!data.level) { + // log unhandled errors as info + data.level = 'info'; + } + + return data; + } + }).install(); + + window.addEventListener('unhandledrejection', + (event) => Raven.captureException(event.reason) + ); + } + }, + + setUser(user) { + Raven.setUserContext({ + username: user.username, + email: user.email, + id: user.id + }); + } +}; + +[ + // 'fatal', + 'error', + 'warning', + 'info', + 'debug' +].forEach((level) => { + level = level === 'warning' ? 'warn' : level; + + logger[level] = (message, context) => { + if (isTest) { + return; + } + + console[level](message, context); + + Raven.captureException(message, { + level, + extra: context + }) + }; +}); + +export default logger; diff --git a/webpack.config.js b/webpack.config.js index d3e2c82..367b3a8 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,6 +13,8 @@ const cssImport = require('postcss-import'); const rootPath = path.resolve('./src'); const outputPath = path.join(__dirname, 'dist'); +const packageJson = require('./package.json'); + var config = {}; try { config = require('./config/env.js'); @@ -105,12 +107,14 @@ const webpackConfig = { plugins: [ new webpack.DefinePlugin({ + 'window.sentryCdn': config.sentryCdn ? JSON.stringify(config.sentryCdn) : undefined, 'process.env': { - NODE_ENV: JSON.stringify(process.env.NODE_ENV) - }, - __DEV__: !isProduction, - __TEST__: isTest, - __PROD__: isProduction + NODE_ENV: JSON.stringify(process.env.NODE_ENV), + __VERSION__: JSON.stringify(packageJson.version), + __DEV__: !isProduction, + __TEST__: isTest, + __PROD__: isProduction + } }), new HtmlWebpackPlugin({ template: 'src/index.ejs', @@ -246,7 +250,7 @@ if (isProduction) { webpackConfig.devtool = false; - webpackConfig.entry.vendor = Object.keys(require('./package.json').dependencies); + webpackConfig.entry.vendor = Object.keys(packageJson.dependencies); } else { webpackConfig.plugins.push( new webpack.DllReferencePlugin({