From 26b30a031dacb23cc0a8ec742ece972acdd48594 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 04:36:36 -0400 Subject: [PATCH 01/11] sentry - move isBrave decoration to insides of try-catch --- app/scripts/lib/setupRaven.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupRaven.js index e6e511640..e1dc4bb8b 100644 --- a/app/scripts/lib/setupRaven.js +++ b/app/scripts/lib/setupRaven.js @@ -24,10 +24,11 @@ function setupRaven (opts) { const client = Raven.config(ravenTarget, { release, transport: function (opts) { - opts.data.extra.isBrave = isBrave const report = opts.data try { + // mark browser as brave or not + report.extra.isBrave = isBrave // handle error-like non-error exceptions rewriteErrorLikeExceptions(report) // simplify certain complex error messages (e.g. Ethjs) From fb1b8d42ac09982b0844ebfd5d4e0169383c983f Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 04:40:23 -0400 Subject: [PATCH 02/11] sentry - update raven-js --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09b66d261..7be0ccbce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10390,7 +10390,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -27091,9 +27091,9 @@ } }, "raven-js": { - "version": "3.24.2", - "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.24.2.tgz", - "integrity": "sha512-Dy/FHDxuo5pXywVf8Nrs5utB2juMATpkxWGqHjVbpFD3m8CaWYLvkB5SEXjWFUZ5GvUsrBVVQ+Dfcp0x6Z7SOg==" + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.27.0.tgz", + "integrity": "sha512-vChdOL+yzecfnGA+B5EhEZkJ3kY3KlMzxEhShKh6Vdtooyl0yZfYNFQfYzgMf2v4pyQa+OTZ5esTxxgOOZDHqw==" }, "raw-body": { "version": "2.3.2", diff --git a/package.json b/package.json index c994acc2f..6c2773623 100644 --- a/package.json +++ b/package.json @@ -186,7 +186,7 @@ "pumpify": "^1.3.4", "qrcode-npm": "0.0.3", "ramda": "^0.24.1", - "raven-js": "^3.24.2", + "raven-js": "^3.27.0", "react": "^15.6.2", "react-addons-css-transition-group": "^15.6.0", "react-dom": "^15.6.2", From 65aa0a1d14b0b18d77b537b216d03ce5d9fca725 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 04:51:03 -0400 Subject: [PATCH 03/11] blacklist - throw errors on request/parse failure --- app/scripts/controllers/blacklist.js | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js index 89c7cc888..5a5ec1c31 100644 --- a/app/scripts/controllers/blacklist.js +++ b/app/scripts/controllers/blacklist.js @@ -83,8 +83,23 @@ class BlacklistController { * */ async updatePhishingList () { - const response = await fetch('https://api.infura.io/v2/blacklist') - const phishing = await response.json() + // make request + let response + try { + response = await fetch('https://api.infura.io/v2/blacklist') + } catch (err) { + throw new Error(`BlacklistController - failed to fetch blacklist:\n${err.stack}`) + } + // parse response + let rawResponse + let phishing + try { + const rawResponse = await response.text() + phishing = JSON.parse(rawResponse) + } catch (err) { + throw new Error(`BlacklistController - failed to parse blacklist:\n${rawResponse}`) + } + // update current blacklist this.store.updateState({ phishing }) this._setupPhishingDetector(phishing) return phishing @@ -97,9 +112,9 @@ class BlacklistController { */ scheduleUpdates () { if (this._phishingUpdateIntervalRef) return - this.updatePhishingList().catch(log.warn) + this.updatePhishingList() this._phishingUpdateIntervalRef = setInterval(() => { - this.updatePhishingList().catch(log.warn) + this.updatePhishingList() }, POLLING_INTERVAL) } From 2394881511928e414ca99cac2a46f30a7703ae91 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 04:58:19 -0400 Subject: [PATCH 04/11] currency - throw errors on failure --- app/scripts/controllers/currency.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index d5bc5fe2b..619c515fa 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -107,14 +107,28 @@ class CurrencyController { let currentCurrency try { currentCurrency = this.getCurrentCurrency() - const response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) - const parsedResponse = await response.json() + let response + try { + response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) + } catch (err) { + throw new Error(`CurrencyController - Failed to request currency from Infura:\n${err.stack}`) + } + let rawResponse + let parsedResponse + try { + rawResponse = await response.text() + parsedResponse = JSON.parse(rawResponse) + } catch () { + throw new Error(`CurrencyController - Failed to parse response "${rawResponse}"`) + } this.setConversionRate(Number(parsedResponse.bid)) this.setConversionDate(Number(parsedResponse.timestamp)) } catch (err) { - log.warn(`MetaMask - Failed to query currency conversion:`, currentCurrency, err) + // reset current conversion rate this.setConversionRate(0) this.setConversionDate('N/A') + // throw error + throw new Error(`CurrencyController - Failed to query rate for currency "${currentCurrency}":\n${err.stack}`) } } From 0b12c4efb197dafce24eed8ae25fb93c0571bce0 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 05:18:47 -0400 Subject: [PATCH 05/11] deps - bump eth-json-rpc-middleware for bugfix --- package-lock.json | 48 +++++++++++++++++++++++++++++++++++++---------- package.json | 2 +- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7be0ccbce..b754db4b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9899,29 +9899,26 @@ } }, "eth-json-rpc-middleware": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-3.1.3.tgz", - "integrity": "sha512-glp/mCefhsqrgVOTTuYlHYiTL+9mMPfaZsuQv4vnRg3kqNigblS1nqARaMeVW9WOM8ssh9TqIFpuUr7JDgNmKQ==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-3.1.5.tgz", + "integrity": "sha512-68POkWUj0zYvxincExjRWXE49cxKDUSrSZn4oDVER5O5mWm0q/xcsLxlcurNFdHPov9APVqCXqzK6n2jUCDfRQ==", "dev": true, "requires": { - "async": "^2.5.0", "btoa": "^1.2.1", "clone": "^2.1.1", "eth-query": "^2.1.2", "eth-sig-util": "^1.4.2", - "eth-tx-summary": "^3.1.2", + "eth-tx-summary": "^3.2.3", "ethereumjs-block": "^1.6.0", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.1.2", - "ethereumjs-vm": "^2.1.0", + "ethereumjs-vm": "^2.4.0", "fetch-ponyfill": "^4.0.0", - "json-rpc-engine": "^3.6.3", + "json-rpc-engine": "^3.8.0", "json-rpc-error": "^2.0.0", "json-stable-stringify": "^1.0.1", "pify": "^3.0.0", - "promise-to-callback": "^1.0.0", - "safe-event-emitter": "^1.0.1", - "tape": "^4.6.3" + "safe-event-emitter": "^1.0.1" }, "dependencies": { "eth-sig-util": { @@ -9957,6 +9954,31 @@ "safe-buffer": "^5.1.1", "secp256k1": "^3.0.1" } + }, + "ethereumjs-vm": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz", + "integrity": "sha512-MJ4lCWa5c6LhahhhvoDKW+YGjK00ZQn0RHHLh4L+WaH1k6Qv7/q3uTluew6sJGNCZdlO0yYMDXYW9qyxLHKlgQ==", + "dev": true, + "requires": { + "async": "^2.1.2", + "async-eventemitter": "^0.2.2", + "ethereumjs-account": "^2.0.3", + "ethereumjs-block": "~1.7.0", + "ethereumjs-common": "~0.4.0", + "ethereumjs-util": "^5.2.0", + "fake-merkle-patricia-tree": "^1.0.1", + "functional-red-black-tree": "^1.0.1", + "merkle-patricia-tree": "^2.1.2", + "rustbn.js": "~0.2.0", + "safe-buffer": "^5.1.1" + } + }, + "rustbn.js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", + "dev": true } } }, @@ -10907,6 +10929,12 @@ } } }, + "ethereumjs-common": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz", + "integrity": "sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q==", + "dev": true + }, "ethereumjs-tx": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.3.tgz", diff --git a/package.json b/package.json index 6c2773623..3b35c6cff 100644 --- a/package.json +++ b/package.json @@ -261,7 +261,7 @@ "eslint-plugin-json": "^1.2.0", "eslint-plugin-mocha": "^5.0.0", "eslint-plugin-react": "^7.4.0", - "eth-json-rpc-middleware": "^3.1.3", + "eth-json-rpc-middleware": "^3.1.5", "eth-keyring-controller": "^3.3.1", "fetch-mock": "^6.5.2", "file-loader": "^1.1.11", From 3e3d4b9ddef032fe81419a516e65eb62ed664cb9 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 05:30:21 -0400 Subject: [PATCH 06/11] sentry - failed txs - namespace txMeta for better readability --- app/scripts/lib/reportFailedTxToSentry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/scripts/lib/reportFailedTxToSentry.js b/app/scripts/lib/reportFailedTxToSentry.js index df5661e59..fc6fbac24 100644 --- a/app/scripts/lib/reportFailedTxToSentry.js +++ b/app/scripts/lib/reportFailedTxToSentry.js @@ -11,6 +11,6 @@ function reportFailedTxToSentry ({ raven, txMeta }) { const errorMessage = 'Transaction Failed: ' + extractEthjsErrorMessage(txMeta.err.message) raven.captureMessage(errorMessage, { // "extra" key is required by Sentry - extra: txMeta, + extra: { txMeta }, }) } From b85ae55cd59b4f8fe52ec75e1b7c6efe52a02e3f Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 06:42:53 -0400 Subject: [PATCH 07/11] fetch debugger - only append source stack if no stack is present --- app/scripts/lib/setupFetchDebugging.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/scripts/lib/setupFetchDebugging.js b/app/scripts/lib/setupFetchDebugging.js index dd87b65a6..c1ef22d21 100644 --- a/app/scripts/lib/setupFetchDebugging.js +++ b/app/scripts/lib/setupFetchDebugging.js @@ -2,7 +2,7 @@ module.exports = setupFetchDebugging // // This is a utility to help resolve cases where `window.fetch` throws a -// `TypeError: Failed to Fetch` without any stack or context for the request +// `TypeError: Failed to Fetch` without any stack or context for the request // https://github.com/getsentry/sentry-javascript/pull/1293 // @@ -17,9 +17,11 @@ function setupFetchDebugging() { try { return await originalFetch.call(window, ...args) } catch (err) { - console.warn('FetchDebugger - fetch encountered an Error', err) - console.warn('FetchDebugger - overriding stack to point of original call') - err.stack = initialStack + if (!err.stack) { + console.warn('FetchDebugger - fetch encountered an Error without a stack', err) + console.warn('FetchDebugger - overriding stack to point of original call') + err.stack = initialStack + } throw err } } From a57d267dcbfa1a75a5ce3295e51825561e42c58d Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 07:08:04 -0400 Subject: [PATCH 08/11] lint fix --- app/scripts/controllers/blacklist.js | 1 - app/scripts/controllers/currency.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js index 5a5ec1c31..6ee89259c 100644 --- a/app/scripts/controllers/blacklist.js +++ b/app/scripts/controllers/blacklist.js @@ -1,7 +1,6 @@ const ObservableStore = require('obs-store') const extend = require('xtend') const PhishingDetector = require('eth-phishing-detect/src/detector') -const log = require('loglevel') // compute phishing lists const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json') diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index 619c515fa..6cb39d39a 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -1,6 +1,5 @@ const ObservableStore = require('obs-store') const extend = require('xtend') -const log = require('loglevel') // every ten minutes const POLLING_INTERVAL = 600000 @@ -118,7 +117,7 @@ class CurrencyController { try { rawResponse = await response.text() parsedResponse = JSON.parse(rawResponse) - } catch () { + } catch (err) { throw new Error(`CurrencyController - Failed to parse response "${rawResponse}"`) } this.setConversionRate(Number(parsedResponse.bid)) From 31175dcb24d836650469775a50289bfc131bcd18 Mon Sep 17 00:00:00 2001 From: kumavis Date: Fri, 19 Oct 2018 07:18:16 -0400 Subject: [PATCH 09/11] blacklist + currency - report error via log instead of throw --- app/scripts/controllers/blacklist.js | 7 +++++-- app/scripts/controllers/currency.js | 10 +++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/scripts/controllers/blacklist.js b/app/scripts/controllers/blacklist.js index 6ee89259c..e55b09d03 100644 --- a/app/scripts/controllers/blacklist.js +++ b/app/scripts/controllers/blacklist.js @@ -1,6 +1,7 @@ const ObservableStore = require('obs-store') const extend = require('xtend') const PhishingDetector = require('eth-phishing-detect/src/detector') +const log = require('loglevel') // compute phishing lists const PHISHING_DETECTION_CONFIG = require('eth-phishing-detect/src/config.json') @@ -87,7 +88,8 @@ class BlacklistController { try { response = await fetch('https://api.infura.io/v2/blacklist') } catch (err) { - throw new Error(`BlacklistController - failed to fetch blacklist:\n${err.stack}`) + log.error(new Error(`BlacklistController - failed to fetch blacklist:\n${err.stack}`)) + return } // parse response let rawResponse @@ -96,7 +98,8 @@ class BlacklistController { const rawResponse = await response.text() phishing = JSON.parse(rawResponse) } catch (err) { - throw new Error(`BlacklistController - failed to parse blacklist:\n${rawResponse}`) + log.error(new Error(`BlacklistController - failed to parse blacklist:\n${rawResponse}`)) + return } // update current blacklist this.store.updateState({ phishing }) diff --git a/app/scripts/controllers/currency.js b/app/scripts/controllers/currency.js index 6cb39d39a..6b82265f6 100644 --- a/app/scripts/controllers/currency.js +++ b/app/scripts/controllers/currency.js @@ -1,5 +1,6 @@ const ObservableStore = require('obs-store') const extend = require('xtend') +const log = require('loglevel') // every ten minutes const POLLING_INTERVAL = 600000 @@ -110,7 +111,8 @@ class CurrencyController { try { response = await fetch(`https://api.infura.io/v1/ticker/eth${currentCurrency.toLowerCase()}`) } catch (err) { - throw new Error(`CurrencyController - Failed to request currency from Infura:\n${err.stack}`) + log.error(new Error(`CurrencyController - Failed to request currency from Infura:\n${err.stack}`)) + return } let rawResponse let parsedResponse @@ -118,7 +120,8 @@ class CurrencyController { rawResponse = await response.text() parsedResponse = JSON.parse(rawResponse) } catch (err) { - throw new Error(`CurrencyController - Failed to parse response "${rawResponse}"`) + log.error(new Error(`CurrencyController - Failed to parse response "${rawResponse}"`)) + return } this.setConversionRate(Number(parsedResponse.bid)) this.setConversionDate(Number(parsedResponse.timestamp)) @@ -127,7 +130,8 @@ class CurrencyController { this.setConversionRate(0) this.setConversionDate('N/A') // throw error - throw new Error(`CurrencyController - Failed to query rate for currency "${currentCurrency}":\n${err.stack}`) + log.error(new Error(`CurrencyController - Failed to query rate for currency "${currentCurrency}":\n${err.stack}`)) + return } } From e3fda83ab209af7836ba93bfaba215c271d73e8a Mon Sep 17 00:00:00 2001 From: kumavis Date: Sat, 20 Oct 2018 02:22:50 -0400 Subject: [PATCH 10/11] sentry - replace raven-js with sentry/browser --- app/scripts/background.js | 12 ++-- app/scripts/lib/reportFailedTxToSentry.js | 4 +- .../lib/{setupRaven.js => setupSentry.js} | 70 ++++++++----------- app/scripts/ui.js | 4 +- package-lock.json | 57 +++++++++++++-- package.json | 2 +- 6 files changed, 93 insertions(+), 56 deletions(-) rename app/scripts/lib/{setupRaven.js => setupSentry.js} (52%) diff --git a/app/scripts/background.js b/app/scripts/background.js index 509a0001d..2455608aa 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -23,7 +23,7 @@ const createStreamSink = require('./lib/createStreamSink') const NotificationManager = require('./lib/notification-manager.js') const MetamaskController = require('./metamask-controller') const rawFirstTimeState = require('./first-time-state') -const setupRaven = require('./lib/setupRaven') +const setupSentry = require('./lib/setupSentry') const reportFailedTxToSentry = require('./lib/reportFailedTxToSentry') const setupMetamaskMeshMetrics = require('./lib/setupMetamaskMeshMetrics') const EdgeEncryptor = require('./edge-encryptor') @@ -50,7 +50,7 @@ global.METAMASK_NOTIFIER = notificationManager // setup sentry error reporting const release = platform.getVersion() -const raven = setupRaven({ release }) +const sentry = setupSentry({ release }) // browser check if it is Edge - https://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser // Internet Explorer 6-11 @@ -197,14 +197,14 @@ async function loadStateFromPersistence () { // we were able to recover (though it might be old) versionedData = diskStoreState const vaultStructure = getObjStructure(versionedData) - raven.captureMessage('MetaMask - Empty vault found - recovered from diskStore', { + sentry.captureMessage('MetaMask - Empty vault found - recovered from diskStore', { // "extra" key is required by Sentry extra: { vaultStructure }, }) } else { // unable to recover, clear state versionedData = migrator.generateInitialState(firstTimeState) - raven.captureMessage('MetaMask - Empty vault found - unable to recover') + sentry.captureMessage('MetaMask - Empty vault found - unable to recover') } } @@ -212,7 +212,7 @@ async function loadStateFromPersistence () { migrator.on('error', (err) => { // get vault structure without secrets const vaultStructure = getObjStructure(versionedData) - raven.captureException(err, { + sentry.captureException(err, { // "extra" key is required by Sentry extra: { vaultStructure }, }) @@ -279,7 +279,7 @@ function setupController (initState, initLangCode) { if (status !== 'failed') return const txMeta = controller.txController.txStateManager.getTx(txId) try { - reportFailedTxToSentry({ raven, txMeta }) + reportFailedTxToSentry({ sentry, txMeta }) } catch (e) { console.error(e) } diff --git a/app/scripts/lib/reportFailedTxToSentry.js b/app/scripts/lib/reportFailedTxToSentry.js index fc6fbac24..de4d57145 100644 --- a/app/scripts/lib/reportFailedTxToSentry.js +++ b/app/scripts/lib/reportFailedTxToSentry.js @@ -7,9 +7,9 @@ module.exports = reportFailedTxToSentry // for sending to sentry // -function reportFailedTxToSentry ({ raven, txMeta }) { +function reportFailedTxToSentry ({ sentry, txMeta }) { const errorMessage = 'Transaction Failed: ' + extractEthjsErrorMessage(txMeta.err.message) - raven.captureMessage(errorMessage, { + sentry.captureMessage(errorMessage, { // "extra" key is required by Sentry extra: { txMeta }, }) diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupSentry.js similarity index 52% rename from app/scripts/lib/setupRaven.js rename to app/scripts/lib/setupSentry.js index e1dc4bb8b..aa8d72194 100644 --- a/app/scripts/lib/setupRaven.js +++ b/app/scripts/lib/setupSentry.js @@ -1,59 +1,49 @@ -const Raven = require('raven-js') +const Sentry = require('@sentry/browser') const METAMASK_DEBUG = process.env.METAMASK_DEBUG const extractEthjsErrorMessage = require('./extractEthjsErrorMessage') -const PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' -const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' +const SENTRY_DSN_PROD = 'https://3567c198f8a8412082d32655da2961d0@sentry.io/273505' +const SENTRY_DSN_DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' -module.exports = setupRaven +module.exports = setupSentry -// Setup raven / sentry remote error reporting -function setupRaven (opts) { +// Setup sentry remote error reporting +function setupSentry (opts) { const { release } = opts - let ravenTarget + let sentryTarget // detect brave const isBrave = Boolean(window.chrome.ipcRenderer) if (METAMASK_DEBUG) { - console.log('Setting up Sentry Remote Error Reporting: DEV') - ravenTarget = DEV + console.log('Setting up Sentry Remote Error Reporting: SENTRY_DSN_DEV') + sentryTarget = SENTRY_DSN_DEV } else { - console.log('Setting up Sentry Remote Error Reporting: PROD') - ravenTarget = PROD + console.log('Setting up Sentry Remote Error Reporting: SENTRY_DSN_PROD') + sentryTarget = SENTRY_DSN_PROD } - const client = Raven.config(ravenTarget, { + Sentry.init({ + dsn: sentryTarget, + debug: METAMASK_DEBUG, release, - transport: function (opts) { - const report = opts.data - - try { - // mark browser as brave or not - report.extra.isBrave = isBrave - // handle error-like non-error exceptions - rewriteErrorLikeExceptions(report) - // simplify certain complex error messages (e.g. Ethjs) - simplifyErrorMessages(report) - // modify report urls - rewriteReportUrls(report) - } catch (err) { - console.warn(err) - } - // make request normally - client._makeRequest(opts) - }, + beforeSend: (report) => rewriteReport(report), }) - client.install() - return Raven -} - -function rewriteErrorLikeExceptions (report) { - // handle errors that lost their error-ness in serialization (e.g. dnode) - rewriteErrorMessages(report, (errorMessage) => { - if (!errorMessage.includes('Non-Error exception captured with keys:')) return errorMessage - if (!(report.extra && report.extra.__serialized__ && report.extra.__serialized__.message)) return errorMessage - return `Non-Error Exception: ${report.extra.__serialized__.message}` + Sentry.configureScope(scope => { + scope.setExtra('isBrave', isBrave) }) + + function rewriteReport(report) { + try { + // simplify certain complex error messages (e.g. Ethjs) + simplifyErrorMessages(report) + // modify report urls + rewriteReportUrls(report) + } catch (err) { + console.warn(err) + } + } + + return Sentry } function simplifyErrorMessages (report) { diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 98a036338..8893ceaad 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -9,7 +9,7 @@ const extension = require('extensionizer') const ExtensionPlatform = require('./platforms/extension') const NotificationManager = require('./lib/notification-manager') const notificationManager = new NotificationManager() -const setupRaven = require('./lib/setupRaven') +const setupSentry = require('./lib/setupSentry') const log = require('loglevel') start().catch(log.error) @@ -21,7 +21,7 @@ async function start () { // setup sentry error reporting const release = global.platform.getVersion() - setupRaven({ release }) + setupSentry({ release }) // inject css // const css = MetaMaskUiCss() diff --git a/package-lock.json b/package-lock.json index b754db4b8..dc63d8b91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -489,6 +489,16 @@ } } }, + "@sentry/browser": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-4.1.1.tgz", + "integrity": "sha512-rmkGlTh0AL3Jf0DvF3BluChIyzPkkYpNgIwEHjxTUiLp6BQdgwakZuzBqSPJrEs+jMsKMoesOuJ/fAAG0K7+Ew==", + "requires": { + "@sentry/core": "4.1.1", + "@sentry/types": "4.1.0", + "@sentry/utils": "4.1.1" + } + }, "@sentry/cli": { "version": "1.30.3", "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.30.3.tgz", @@ -531,6 +541,48 @@ } } }, + "@sentry/core": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-4.1.1.tgz", + "integrity": "sha512-QJExTxZ1ZA5P/To5gOwd3sowukXW0N/Q9nfu8biRDNa+YURn6ElLjO0fD6eIBqX1f3npo/kTiWZwFBc7LXEzSg==", + "requires": { + "@sentry/hub": "4.1.1", + "@sentry/minimal": "4.1.1", + "@sentry/types": "4.1.0", + "@sentry/utils": "4.1.1" + } + }, + "@sentry/hub": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-4.1.1.tgz", + "integrity": "sha512-VmcZOgcbFjJzK1oQNwcFP/wgfoWQr24dFv1C0uwdXldNXx3mwyUVkomvklBHz90HwiahsI/gCc+ZmbC3ECQk2Q==", + "requires": { + "@sentry/types": "4.1.0", + "@sentry/utils": "4.1.1" + } + }, + "@sentry/minimal": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-4.1.1.tgz", + "integrity": "sha512-xRKWA46OGnZinJyTljDUel53emPP9mb/XNi/kF6SBaVDOUXl7HAB8kP7Bn7eLBwOanxN8PbYoAzh/lIQXWTmDg==", + "requires": { + "@sentry/hub": "4.1.1", + "@sentry/types": "4.1.0" + } + }, + "@sentry/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-4.1.0.tgz", + "integrity": "sha512-KY7B9wYs1NACHlYzG4OuP6k4uQJkyDPJppftjj3NJYShfwdDTO1I2Swkhhb5dJMEMMMpBJGxXmiqZ2mX5ErISQ==" + }, + "@sentry/utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-4.1.1.tgz", + "integrity": "sha512-XMvGqAWATBrRkOF0lkt0Ij8of2mRmp4WeFTUAgiKzCekxfUBLBaTb4wTaFXz1cnnnjVTwcAq72qBRMhHwQ0IIg==", + "requires": { + "@sentry/types": "4.1.0" + } + }, "@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", @@ -27118,11 +27170,6 @@ "eve-raphael": "0.5.0" } }, - "raven-js": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/raven-js/-/raven-js-3.27.0.tgz", - "integrity": "sha512-vChdOL+yzecfnGA+B5EhEZkJ3kY3KlMzxEhShKh6Vdtooyl0yZfYNFQfYzgMf2v4pyQa+OTZ5esTxxgOOZDHqw==" - }, "raw-body": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", diff --git a/package.json b/package.json index 3b35c6cff..ebac62d7f 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ }, "dependencies": { "@material-ui/core": "1.0.0", + "@sentry/browser": "^4.1.1", "@zxing/library": "^0.8.0", "abi-decoder": "^1.0.9", "asmcrypto.js": "0.22.0", @@ -186,7 +187,6 @@ "pumpify": "^1.3.4", "qrcode-npm": "0.0.3", "ramda": "^0.24.1", - "raven-js": "^3.27.0", "react": "^15.6.2", "react-addons-css-transition-group": "^15.6.0", "react-dom": "^15.6.2", From 73ec4e66cb7a476d01371a61692b0d8d9224da04 Mon Sep 17 00:00:00 2001 From: kumavis Date: Sat, 20 Oct 2018 03:14:59 -0400 Subject: [PATCH 11/11] sentry - include app state in ui errors --- app/scripts/lib/setupSentry.js | 8 +++++++- app/scripts/ui.js | 12 +++++++++++- package-lock.json | 6 +++--- package.json | 2 +- ui/app/reducers.js | 26 ++++++++++++++++---------- 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js index aa8d72194..69042bc19 100644 --- a/app/scripts/lib/setupSentry.js +++ b/app/scripts/lib/setupSentry.js @@ -8,7 +8,7 @@ module.exports = setupSentry // Setup sentry remote error reporting function setupSentry (opts) { - const { release } = opts + const { release, getState } = opts let sentryTarget // detect brave const isBrave = Boolean(window.chrome.ipcRenderer) @@ -38,9 +38,15 @@ function setupSentry (opts) { simplifyErrorMessages(report) // modify report urls rewriteReportUrls(report) + // append app state + if (getState) { + const appState = getState() + report.extra.appState = appState + } } catch (err) { console.warn(err) } + return report } return Sentry diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 8893ceaad..c4f6615db 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -21,7 +21,17 @@ async function start () { // setup sentry error reporting const release = global.platform.getVersion() - setupSentry({ release }) + setupSentry({ release, getState }) + // provide app state to append to error logs + function getState() { + // get app state + const state = window.getCleanAppState() + // remove unnecessary data + delete state.localeMessages + delete state.metamask.recentBlocks + // return state to be added to request + return state + } // inject css // const css = MetaMaskUiCss() diff --git a/package-lock.json b/package-lock.json index dc63d8b91..04c2b7014 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6183,9 +6183,9 @@ } }, "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" }, "clone-buffer": { "version": "1.0.0", diff --git a/package.json b/package.json index ebac62d7f..9f56e726a 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "browserify-derequire": "^0.9.4", "browserify-unibabel": "^3.0.0", "classnames": "^2.2.5", - "clone": "^2.1.1", + "clone": "^2.1.2", "copy-to-clipboard": "^3.0.8", "css-loader": "^0.28.11", "currency-formatter": "^1.4.2", diff --git a/ui/app/reducers.js b/ui/app/reducers.js index 80e76d570..e1a982f93 100644 --- a/ui/app/reducers.js +++ b/ui/app/reducers.js @@ -1,3 +1,4 @@ +const clone = require('clone') const extend = require('xtend') const copyToClipboard = require('copy-to-clipboard') @@ -52,19 +53,24 @@ function rootReducer (state, action) { return state } +window.getCleanAppState = function () { + const state = clone(window.METAMASK_CACHED_LOG_STATE) + // append additional information + state.version = global.platform.getVersion() + state.browser = window.navigator.userAgent + // ensure seedWords are not included + if (state.metamask) delete state.metamask.seedWords + if (state.appState.currentView) delete state.appState.currentView.seedWords + return state +} + window.logStateString = function (cb) { - const state = window.METAMASK_CACHED_LOG_STATE - const version = global.platform.getVersion() - const browser = window.navigator.userAgent - return global.platform.getPlatformInfo((err, platform) => { - if (err) { - return cb(err) - } - state.version = version + const state = window.getCleanAppState() + global.platform.getPlatformInfo((err, platform) => { + if (err) return cb(err) state.platform = platform - state.browser = browser const stateString = JSON.stringify(state, removeSeedWords, 2) - return cb(null, stateString) + cb(null, stateString) }) }