From 728617fed2fee99b2accdcf6d2ddc9036c9ad266 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 20 Nov 2018 12:06:10 -0800 Subject: feat(instant): Report errors to rollbar --- packages/instant/src/util/error_reporter.ts | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 packages/instant/src/util/error_reporter.ts (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts new file mode 100644 index 000000000..81a90e7f5 --- /dev/null +++ b/packages/instant/src/util/error_reporter.ts @@ -0,0 +1,68 @@ +import { logUtils } from '@0x/utils'; + +import { ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENVIRONMENT } from '../constants'; + +// Import version of Rollbar designed for embedded components +// See https://docs.rollbar.com/docs/using-rollbarjs-inside-an-embedded-component +// tslint:disable-next-line:no-var-requires +const Rollbar = require('rollbar/dist/rollbar.noconflict.umd'); + +const shouldAllowRollbar = () => { + if (ROLLBAR_ENVIRONMENT === 'development') { + return process.env.ROLLBAR_FORCE_DEVELOPMENT_REPORT ? true : false; + } + return true; +}; + +let rollbar: any; +if (ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENVIRONMENT && shouldAllowRollbar()) { + rollbar = new Rollbar({ + accessToken: ROLLBAR_CLIENT_TOKEN, + captureUncaught: true, + captureUnhandledRejections: true, + enabled: true, + itemsPerMinute: 10, + maxItems: 500, + payload: { + environment: ROLLBAR_ENVIRONMENT, + client: { + javascript: { + source_map_enabled: true, + code_version: process.env.GIT_SHA, + guess_uncaught_frames: true, + }, + }, + }, + uncaughtErrorLevel: 'error', + ignoredMessages: [ + // Errors from the third-party scripts + 'Script error', + // Network errors or ad-blockers + 'TypeError: Failed to fetch', + 'Exchange has not been deployed to detected network (network/artifact mismatch)', + // Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE + "undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')", + // Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging + 'SecurityError (DOM Exception 18)', + ], + }); +} + +export const setupRollbar = (): any => { + return rollbar as any; +}; + +export const errorReporter = { + report(err: Error): void { + if (!rollbar) { + logUtils.log('Not reporting to rollbar because not configured', err); + return; + } + + rollbar.error(err, (rollbarErr: Error) => { + if (rollbarErr) { + logUtils.log(`Error reporting to rollbar, ignoring: ${rollbarErr}`); + } + }); + }, +}; -- cgit v1.2.3 From 934570d12fae9c67ae18fc914577f02a51af3bca Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 20 Nov 2018 13:18:47 -0800 Subject: Explicit error reporting --- packages/instant/src/util/buy_quote_updater.ts | 4 +++- packages/instant/src/util/gas_price_estimator.ts | 5 ++++- packages/instant/src/util/heap.ts | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 2fd16d781..6cb5e41b6 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -9,6 +9,7 @@ import { Action, actions } from '../redux/actions'; import { AffiliateInfo, ERC20Asset } from '../types'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; +import { errorReporter } from '../util/error_reporter'; export const buyQuoteUpdater = { updateBuyQuoteAsync: async ( @@ -49,8 +50,9 @@ export const buyQuoteUpdater = { } else { throw error; } + } else { + errorReporter.report(error); } - // TODO: report to error reporter on else return; } diff --git a/packages/instant/src/util/gas_price_estimator.ts b/packages/instant/src/util/gas_price_estimator.ts index 6b15809a3..332c8d00a 100644 --- a/packages/instant/src/util/gas_price_estimator.ts +++ b/packages/instant/src/util/gas_price_estimator.ts @@ -7,6 +7,8 @@ import { GWEI_IN_WEI, } from '../constants'; +import { errorReporter } from './error_reporter'; + interface EthGasStationResult { average: number; fastestWait: number; @@ -42,8 +44,9 @@ export class GasPriceEstimator { let fetchedAmount: GasInfo | undefined; try { fetchedAmount = await fetchFastAmountInWeiAsync(); - } catch { + } catch (e) { fetchedAmount = undefined; + errorReporter.report(e); } if (fetchedAmount) { diff --git a/packages/instant/src/util/heap.ts b/packages/instant/src/util/heap.ts index 78ec3b3cc..10670b278 100644 --- a/packages/instant/src/util/heap.ts +++ b/packages/instant/src/util/heap.ts @@ -5,6 +5,7 @@ import * as _ from 'lodash'; import { HEAP_ANALYTICS_ID } from '../constants'; import { AnalyticsEventOptions, AnalyticsUserOptions } from './analytics'; +import { errorReporter } from './error_reporter'; export interface HeapAnalytics { loaded: boolean; @@ -105,8 +106,8 @@ export const heapUtil = { heapFunctionCall(curHeap); } catch (e) { // We never want analytics to crash our React component - // TODO(sk): error reporter here logUtils.log('Analytics error', e); + errorReporter.report(e); } } }, -- cgit v1.2.3 From 094aabfcee8828eb5c5ba452edda306ef04757ce Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 20 Nov 2018 13:28:28 -0800 Subject: Linting --- packages/instant/src/util/error_reporter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index 81a90e7f5..a03b5e65e 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -49,7 +49,7 @@ if (ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENVIRONMENT && shouldAllowRollbar()) { } export const setupRollbar = (): any => { - return rollbar as any; + return rollbar; }; export const errorReporter = { -- cgit v1.2.3 From 35b505114842b8c8eac838fff8588adf17f54b45 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 21 Nov 2018 09:23:19 -0800 Subject: Always report unexpected errors. Move error message generation into helper function, and add tests --- packages/instant/src/util/asset.ts | 17 +++++++++++++++ packages/instant/src/util/buy_quote_updater.ts | 29 +++++++------------------- 2 files changed, 25 insertions(+), 21 deletions(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 40560d3eb..08f3642e3 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -1,3 +1,4 @@ +import { AssetBuyerError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; import * as _ from 'lodash'; @@ -106,4 +107,20 @@ export const assetUtils = { ); return _.compact(erc20sOrUndefined); }, + assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => { + if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { + const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); + return `Not enough ${assetName} available`; + } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { + return 'Not enough ZRX available'; + } else if ( + error.message === AssetBuyerError.StandardRelayerApiError || + error.message.startsWith(AssetBuyerError.AssetUnavailable) + ) { + const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); + return `${assetName} is currently unavailable`; + } + + return undefined; + }, }; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 6cb5e41b6..4f97622e1 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -30,30 +30,17 @@ export const buyQuoteUpdater = { try { newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); } catch (error) { - if (options.dispatchErrors) { - dispatch(actions.setQuoteRequestStateFailure()); - let errorMessage; - if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { - const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); - errorMessage = `Not enough ${assetName} available`; - } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { - errorMessage = 'Not enough ZRX available'; - } else if ( - error.message === AssetBuyerError.StandardRelayerApiError || - error.message.startsWith(AssetBuyerError.AssetUnavailable) - ) { - const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); - errorMessage = `${assetName} is currently unavailable`; - } - if (!_.isUndefined(errorMessage)) { - errorFlasher.flashNewErrorMessage(dispatch, errorMessage); - } else { - throw error; - } - } else { + const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error); + + if (_.isUndefined(errorMessage)) { + // This is an unknown error, report it to rollbar errorReporter.report(error); } + if (options.dispatchErrors) { + dispatch(actions.setQuoteRequestStateFailure()); + errorFlasher.flashNewErrorMessage(dispatch, errorMessage || 'Error fetching price, please try again'); + } return; } // We have a successful new buy quote -- cgit v1.2.3 From 22a31246622e7139185d080cae9bef275087e245 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 21 Nov 2018 09:35:24 -0800 Subject: Move rollbar setup into function, move setting up into provider --- packages/instant/src/util/error_reporter.ts | 66 ++++++++++++++--------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index a03b5e65e..c5766b469 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -1,4 +1,5 @@ import { logUtils } from '@0x/utils'; +import * as _ from 'lodash'; import { ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENVIRONMENT } from '../constants'; @@ -15,41 +16,40 @@ const shouldAllowRollbar = () => { }; let rollbar: any; -if (ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENVIRONMENT && shouldAllowRollbar()) { - rollbar = new Rollbar({ - accessToken: ROLLBAR_CLIENT_TOKEN, - captureUncaught: true, - captureUnhandledRejections: true, - enabled: true, - itemsPerMinute: 10, - maxItems: 500, - payload: { - environment: ROLLBAR_ENVIRONMENT, - client: { - javascript: { - source_map_enabled: true, - code_version: process.env.GIT_SHA, - guess_uncaught_frames: true, +// Configures rollbar and sets up error catching +export const setupRollbar = (): any => { + if (_.isUndefined(rollbar) && ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENVIRONMENT && shouldAllowRollbar()) { + rollbar = new Rollbar({ + accessToken: ROLLBAR_CLIENT_TOKEN, + captureUncaught: true, + captureUnhandledRejections: true, + enabled: true, + itemsPerMinute: 10, + maxItems: 500, + payload: { + environment: ROLLBAR_ENVIRONMENT, + client: { + javascript: { + source_map_enabled: true, + code_version: process.env.GIT_SHA, + guess_uncaught_frames: true, + }, }, }, - }, - uncaughtErrorLevel: 'error', - ignoredMessages: [ - // Errors from the third-party scripts - 'Script error', - // Network errors or ad-blockers - 'TypeError: Failed to fetch', - 'Exchange has not been deployed to detected network (network/artifact mismatch)', - // Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE - "undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')", - // Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging - 'SecurityError (DOM Exception 18)', - ], - }); -} - -export const setupRollbar = (): any => { - return rollbar; + uncaughtErrorLevel: 'error', + ignoredMessages: [ + // Errors from the third-party scripts + 'Script error', + // Network errors or ad-blockers + 'TypeError: Failed to fetch', + 'Exchange has not been deployed to detected network (network/artifact mismatch)', + // Source: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/7VU0_VvC7mE + "undefined is not an object (evaluating '__gCrWeb.autofill.extractForms')", + // Source: http://stackoverflow.com/questions/43399818/securityerror-from-facebook-and-cross-domain-messaging + 'SecurityError (DOM Exception 18)', + ], + }); + } }; export const errorReporter = { -- cgit v1.2.3 From e2a16f3f336c6787501c6a2366e7793a135009f8 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 21 Nov 2018 10:25:10 -0800 Subject: Use ROLLBAR_ENABLED constant, and change ROLLBAR_ENVIRONMENT to INSTANT_ENVIRONMENT --- packages/instant/src/util/error_reporter.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index c5766b469..89c5b6bd3 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -1,24 +1,17 @@ import { logUtils } from '@0x/utils'; import * as _ from 'lodash'; -import { ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENVIRONMENT } from '../constants'; +import { INSTANT_ENVIRONMENT, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; // Import version of Rollbar designed for embedded components // See https://docs.rollbar.com/docs/using-rollbarjs-inside-an-embedded-component // tslint:disable-next-line:no-var-requires const Rollbar = require('rollbar/dist/rollbar.noconflict.umd'); -const shouldAllowRollbar = () => { - if (ROLLBAR_ENVIRONMENT === 'development') { - return process.env.ROLLBAR_FORCE_DEVELOPMENT_REPORT ? true : false; - } - return true; -}; - let rollbar: any; // Configures rollbar and sets up error catching export const setupRollbar = (): any => { - if (_.isUndefined(rollbar) && ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENVIRONMENT && shouldAllowRollbar()) { + if (_.isUndefined(rollbar) && ROLLBAR_CLIENT_TOKEN && INSTANT_ENVIRONMENT && ROLLBAR_ENABLED) { rollbar = new Rollbar({ accessToken: ROLLBAR_CLIENT_TOKEN, captureUncaught: true, @@ -27,7 +20,7 @@ export const setupRollbar = (): any => { itemsPerMinute: 10, maxItems: 500, payload: { - environment: ROLLBAR_ENVIRONMENT, + environment: INSTANT_ENVIRONMENT, client: { javascript: { source_map_enabled: true, -- cgit v1.2.3 From 93672c01afd19f07daa89934fc8d29caefbec2f6 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 21 Nov 2018 10:54:10 -0800 Subject: Linting --- packages/instant/src/util/buy_quote_updater.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 4f97622e1..172b50d2a 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -1,4 +1,4 @@ -import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { AssetBuyer, BuyQuote } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; -- cgit v1.2.3 From c6ae7b8d3f720f637db2d5ec9abee14cc00fb7a7 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 21 Nov 2018 13:19:26 -0800 Subject: Host whitelist so we don't get errors from embedded site --- packages/instant/src/util/error_reporter.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index 89c5b6bd3..c0ef3e30e 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -1,7 +1,7 @@ import { logUtils } from '@0x/utils'; import * as _ from 'lodash'; -import { INSTANT_ENVIRONMENT, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; +import { EMBEDDED_DOMAINS, INSTANT_ENVIRONMENT, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; // Import version of Rollbar designed for embedded components // See https://docs.rollbar.com/docs/using-rollbarjs-inside-an-embedded-component @@ -29,6 +29,7 @@ export const setupRollbar = (): any => { }, }, }, + hostWhiteList: EMBEDDED_DOMAINS, uncaughtErrorLevel: 'error', ignoredMessages: [ // Errors from the third-party scripts -- cgit v1.2.3 From 717a3bce8cd0d4cb782918b3ad806f6c1bdb825e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 26 Nov 2018 09:12:51 -0800 Subject: EMBEDDED_DOMAINS -> HOST_DOMAINS --- packages/instant/src/util/error_reporter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant/src/util') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index c0ef3e30e..8e21c8881 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -1,7 +1,7 @@ import { logUtils } from '@0x/utils'; import * as _ from 'lodash'; -import { EMBEDDED_DOMAINS, INSTANT_ENVIRONMENT, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; +import { HOST_DOMAINS, INSTANT_ENVIRONMENT, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; // Import version of Rollbar designed for embedded components // See https://docs.rollbar.com/docs/using-rollbarjs-inside-an-embedded-component @@ -29,7 +29,7 @@ export const setupRollbar = (): any => { }, }, }, - hostWhiteList: EMBEDDED_DOMAINS, + hostWhiteList: HOST_DOMAINS, uncaughtErrorLevel: 'error', ignoredMessages: [ // Errors from the third-party scripts -- cgit v1.2.3