diff --git a/package-lock.json b/package-lock.json index efcef3b..9124914 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,15 +4,15 @@ "requires": true, "packages": { "": { - "name": "react-starter", "license": "MIT", "dependencies": { "@hookform/resolvers": "2.8.0", "@reduxjs/toolkit": "1.6.1", + "@sentry/browser": "6.13.2", "axios": "0.21.1", "classnames": "2.3.1", "core-js": "3.16.4", - "history": "5.0.1", + "history": "4.10.1", "lodash": "4.17.21", "normalize.css": "8.0.1", "postcss": "8.3.6", @@ -3712,6 +3712,106 @@ } } }, + "node_modules/@sentry/browser": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.2.tgz", + "integrity": "sha512-bkFXK4vAp2UX/4rQY0pj2Iky55Gnwr79CtveoeeMshoLy5iDgZ8gvnLNAz7om4B9OQk1u7NzLEa4IXAmHTUyag==", + "dependencies": { + "@sentry/core": "6.13.2", + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/browser/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/core": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.2.tgz", + "integrity": "sha512-snXNNFLwlS7yYxKTX4DBXebvJK+6ikBWN6noQ1CHowvM3ReFBlrdrs0Z0SsSFEzXm2S4q7f6HHbm66GSQZ/8FQ==", + "dependencies": { + "@sentry/hub": "6.13.2", + "@sentry/minimal": "6.13.2", + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/hub": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.2.tgz", + "integrity": "sha512-sppSuJdNMiMC/vFm/dQowCBh11uTrmvks00fc190YWgxHshodJwXMdpc+pN61VSOmy2QA4MbQ5aMAgHzPzel3A==", + "dependencies": { + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/minimal": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.2.tgz", + "integrity": "sha512-6iJfEvHzzpGBHDfLxSHcGObh73XU1OSQKWjuhDOe7UQDyI4BQmTfcXAC+Fr8sm8C/tIsmpVi/XJhs8cubFdSMw==", + "dependencies": { + "@sentry/hub": "6.13.2", + "@sentry/types": "6.13.2", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, + "node_modules/@sentry/types": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.2.tgz", + "integrity": "sha512-6WjGj/VjjN8LZDtqJH5ikeB1o39rO1gYS6anBxiS3d0sXNBb3Ux0pNNDFoBxQpOhmdDHXYS57MEptX9EV82gmg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.2.tgz", + "integrity": "sha512-foF4PbxqPMWNbuqdXkdoOmKm3quu3PP7Q7j/0pXkri4DtCuvF/lKY92mbY0V9rHS/phCoj+3/Se5JvM2ymh2/w==", + "dependencies": { + "@sentry/types": "6.13.2", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "node_modules/@storybook/addon-actions": { "version": "6.4.0-alpha.33", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.4.0-alpha.33.tgz", @@ -20377,11 +20477,16 @@ } }, "node_modules/history": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/history/-/history-5.0.1.tgz", - "integrity": "sha512-5qC/tFUKfVci5kzgRxZxN5Mf1CV8NmJx9ByaPX0YTLx5Vz3Svh7NYp6eA4CpDq4iA9D0C1t8BNIfvQIrUI3mVw==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", "dependencies": { - "@babel/runtime": "^7.7.6" + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" } }, "node_modules/hmac-drbg": { @@ -29124,32 +29229,6 @@ "react": ">=15" } }, - "node_modules/react-router-dom/node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, - "node_modules/react-router/node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, "node_modules/react-select": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-select/-/react-select-4.3.1.tgz", @@ -38464,6 +38543,98 @@ "any-observable": "^0.3.0" } }, + "@sentry/browser": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.13.2.tgz", + "integrity": "sha512-bkFXK4vAp2UX/4rQY0pj2Iky55Gnwr79CtveoeeMshoLy5iDgZ8gvnLNAz7om4B9OQk1u7NzLEa4IXAmHTUyag==", + "requires": { + "@sentry/core": "6.13.2", + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/core": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.13.2.tgz", + "integrity": "sha512-snXNNFLwlS7yYxKTX4DBXebvJK+6ikBWN6noQ1CHowvM3ReFBlrdrs0Z0SsSFEzXm2S4q7f6HHbm66GSQZ/8FQ==", + "requires": { + "@sentry/hub": "6.13.2", + "@sentry/minimal": "6.13.2", + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/hub": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.13.2.tgz", + "integrity": "sha512-sppSuJdNMiMC/vFm/dQowCBh11uTrmvks00fc190YWgxHshodJwXMdpc+pN61VSOmy2QA4MbQ5aMAgHzPzel3A==", + "requires": { + "@sentry/types": "6.13.2", + "@sentry/utils": "6.13.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/minimal": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.13.2.tgz", + "integrity": "sha512-6iJfEvHzzpGBHDfLxSHcGObh73XU1OSQKWjuhDOe7UQDyI4BQmTfcXAC+Fr8sm8C/tIsmpVi/XJhs8cubFdSMw==", + "requires": { + "@sentry/hub": "6.13.2", + "@sentry/types": "6.13.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@sentry/types": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.13.2.tgz", + "integrity": "sha512-6WjGj/VjjN8LZDtqJH5ikeB1o39rO1gYS6anBxiS3d0sXNBb3Ux0pNNDFoBxQpOhmdDHXYS57MEptX9EV82gmg==" + }, + "@sentry/utils": { + "version": "6.13.2", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.13.2.tgz", + "integrity": "sha512-foF4PbxqPMWNbuqdXkdoOmKm3quu3PP7Q7j/0pXkri4DtCuvF/lKY92mbY0V9rHS/phCoj+3/Se5JvM2ymh2/w==", + "requires": { + "@sentry/types": "6.13.2", + "tslib": "^1.9.3" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, "@storybook/addon-actions": { "version": "6.4.0-alpha.33", "resolved": "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.4.0-alpha.33.tgz", @@ -51648,11 +51819,16 @@ "dev": true }, "history": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/history/-/history-5.0.1.tgz", - "integrity": "sha512-5qC/tFUKfVci5kzgRxZxN5Mf1CV8NmJx9ByaPX0YTLx5Vz3Svh7NYp6eA4CpDq4iA9D0C1t8BNIfvQIrUI3mVw==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", "requires": { - "@babel/runtime": "^7.7.6" + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" } }, "hmac-drbg": { @@ -58251,21 +58427,6 @@ "react-is": "^16.6.0", "tiny-invariant": "^1.0.2", "tiny-warning": "^1.0.0" - }, - "dependencies": { - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - } } }, "react-router-dom": { @@ -58280,21 +58441,6 @@ "react-router": "5.2.1", "tiny-invariant": "^1.0.2", "tiny-warning": "^1.0.0" - }, - "dependencies": { - "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", - "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - } } }, "react-select": { diff --git a/package.json b/package.json index d3f790d..241b01e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "@hookform/resolvers": "2.8.0", "@reduxjs/toolkit": "1.6.1", + "@sentry/browser": "6.13.2", "axios": "0.21.1", "classnames": "2.3.1", "core-js": "3.16.4", diff --git a/src/config/development.json b/src/config/development.json index 82e2ec8..0b760db 100644 --- a/src/config/development.json +++ b/src/config/development.json @@ -1,5 +1,6 @@ { "apiUrl": "http://localhost:3001", "landingUrl": "http://localhost:3000", - "webSocketUrl": "http://localhost:8082" + "webSocketUrl": "http://localhost:8082", + "dsnSentryUrl": "https://da17bd641d7e4371b54b809cb2f03896@o1018683.ingest.sentry.io/5984511" } diff --git a/src/config/production.json b/src/config/production.json index 0967ef4..b80d5b3 100644 --- a/src/config/production.json +++ b/src/config/production.json @@ -1 +1,3 @@ -{} +{ + "dsnSentryUrl": "https://da17bd641d7e4371b54b809cb2f03896@o1018683.ingest.sentry.io/5984511" +} diff --git a/src/config/staging.json b/src/config/staging.json index 0967ef4..b80d5b3 100644 --- a/src/config/staging.json +++ b/src/config/staging.json @@ -1 +1,3 @@ -{} +{ + "dsnSentryUrl": "https://da17bd641d7e4371b54b809cb2f03896@o1018683.ingest.sentry.io/5984511" +} diff --git a/src/helpers/validation/index.js b/src/helpers/validation/index.js index 9fb502a..53b226d 100644 --- a/src/helpers/validation/index.js +++ b/src/helpers/validation/index.js @@ -1,6 +1,7 @@ import * as yup from 'yup'; import get from 'lodash/get'; import set from 'lodash/set'; +import * as Sentry from '@sentry/browser'; const yupOptions = { abortEarly: false, @@ -35,6 +36,7 @@ export const validate = async (obj, schema) => { }; } catch (error) { const errors = parseErrors(error); + Sentry.captureException(errors); return { value: obj, errors, @@ -53,6 +55,7 @@ export const validateField = async (obj, field, schema) => { }; } catch (error) { const errors = parseErrors(error, field); + Sentry.captureException(errors); return { value: obj, errors, diff --git a/src/hooks/useHandleError.js b/src/hooks/useHandleError.js index 4a40aad..13b28ab 100644 --- a/src/hooks/useHandleError.js +++ b/src/hooks/useHandleError.js @@ -4,13 +4,14 @@ export default function useHandleError() { const { toastError } = useToast(); return (e, setError) => { - const { errors: { _global, ...errors } } = e.data; + const { errors } = e.data || {}; + const { _global, ...errorsRest } = errors || {}; if (_global) toastError(_global[0]); - if (setError) { - Object.keys(errors).forEach((key) => { - setError(key, { message: errors[key].join(' ') }, { shouldFocus: true }); + if (setError && errorsRest) { + Object.keys(errorsRest).forEach((key) => { + setError(key, { message: errorsRest[key].join(' ') }, { shouldFocus: true }); }); } }; diff --git a/src/index.jsx b/src/index.jsx index b8a3ffd..427abee 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,11 +1,18 @@ import 'core-js/stable'; import 'regenerator-runtime/runtime'; +import * as Sentry from '@sentry/browser'; import React from 'react'; import ReactDOM from 'react-dom'; +import config from 'config'; + import App from './app'; +Sentry.init({ + dsn: config.dsnSentryUrl, +}); + function render() { ReactDOM.render(, document.querySelector('#root')); } diff --git a/src/pages/profile/profile.jsx b/src/pages/profile/profile.jsx index 1674e08..fd1a1ed 100644 --- a/src/pages/profile/profile.jsx +++ b/src/pages/profile/profile.jsx @@ -2,6 +2,7 @@ import React, { useCallback, useState, useEffect } from 'react'; import * as yup from 'yup'; import { useDispatch, useSelector } from 'react-redux'; import { useFormContext } from 'react-hook-form'; +import * as Sentry from '@sentry/browser'; import useToast from 'hooks/useToast'; import * as userSelectors from 'resources/user/user.selectors'; @@ -72,6 +73,7 @@ const Profile = () => { setAvatarUrl(url); } } catch (error) { + Sentry.captureException(error); toastError(error); } }, [toastError]); @@ -82,6 +84,7 @@ const Profile = () => { const { key } = await filesApi.upload(file); setAvatarFileKey(key); } catch (error) { + Sentry.captureException(error); toastError(error); } };