Adding method to capture one-time Sentry exceptions (#11553)

feature/default_network_editable
ryanml 3 years ago committed by GitHub
parent a96af9e5fc
commit 8cb1557f1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      ui/components/app/transaction-icon/transaction-icon.js
  2. 12
      ui/ducks/app/app.js
  3. 9
      ui/hooks/useTransactionDisplayData.js
  4. 3
      ui/hooks/useTransactionDisplayData.test.js
  5. 1
      ui/store/actionConstants.js
  6. 14
      ui/store/actions.js

@ -1,6 +1,6 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import { captureException } from '@sentry/browser';
import Approve from '../../ui/icon/approve-icon.component';
import Interaction from '../../ui/icon/interaction-icon.component';
import Receive from '../../ui/icon/receive-icon.component';
@ -12,6 +12,7 @@ import {
TRANSACTION_GROUP_STATUSES,
TRANSACTION_STATUSES,
} from '../../../../shared/constants/transaction';
import { captureSingleException } from '../../../store/actions';
const ICON_MAP = {
[TRANSACTION_GROUP_CATEGORIES.APPROVAL]: Approve,
@ -38,17 +39,17 @@ const COLOR_MAP = {
};
export default function TransactionIcon({ status, category }) {
const color = COLOR_MAP[status] || OK_COLOR;
const dispatch = useDispatch();
const color = COLOR_MAP[status] || OK_COLOR;
const Icon = ICON_MAP[category];
if (!Icon) {
captureException(
Error(
dispatch(
captureSingleException(
`The category prop passed to TransactionIcon is not supported. The prop is: ${category}`,
),
);
return <div className="transaction-icon__grey-circle" />;
}

@ -50,6 +50,9 @@ export default function reduceApp(state = {}, action) {
openMetaMaskTabs: {},
currentWindowTab: {},
showWhatsNewPopup: true,
singleExceptions: {
testKey: null,
},
...state,
};
@ -346,6 +349,15 @@ export default function reduceApp(state = {}, action) {
showWhatsNewPopup: false,
};
case actionConstants.CAPTURE_SINGLE_EXCEPTION:
return {
...appState,
singleExceptions: {
...appState.singleExceptions,
[action.value]: null,
},
};
default:
return appState;
}

@ -1,5 +1,4 @@
import { useSelector } from 'react-redux';
import { captureException } from '@sentry/browser';
import { useDispatch, useSelector } from 'react-redux';
import { getKnownMethodData } from '../selectors/selectors';
import {
getStatusKey,
@ -23,6 +22,7 @@ import {
TRANSACTION_GROUP_CATEGORIES,
TRANSACTION_STATUSES,
} from '../../shared/constants/transaction';
import { captureSingleException } from '../store/actions';
import { useI18nContext } from './useI18nContext';
import { useTokenFiatAmount } from './useTokenFiatAmount';
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
@ -58,6 +58,7 @@ import { useCurrentAsset } from './useCurrentAsset';
export function useTransactionDisplayData(transactionGroup) {
// To determine which primary currency to display for swaps transactions we need to be aware
// of which asset, if any, we are viewing at present
const dispatch = useDispatch();
const currentAsset = useCurrentAsset();
const knownTokens = useSelector(getTokens);
const t = useI18nContext();
@ -222,8 +223,8 @@ export function useTransactionDisplayData(transactionGroup) {
title = t('send');
subtitle = t('toAddress', [shortenAddress(recipientAddress)]);
} else {
captureException(
Error(
dispatch(
captureSingleException(
`useTransactionDisplayData does not recognize transaction type. Type received is: ${type}`,
),
);

@ -132,6 +132,8 @@ const renderHookWithRouter = (cb, tokenAddress) => {
};
describe('useTransactionDisplayData', () => {
const dispatch = sinon.spy();
beforeAll(() => {
useSelector = sinon.stub(reactRedux, 'useSelector');
useTokenFiatAmount = sinon.stub(
@ -169,6 +171,7 @@ describe('useTransactionDisplayData', () => {
}
return null;
});
sinon.stub(reactRedux, 'useDispatch').returns(dispatch);
});
afterAll(() => {

@ -30,6 +30,7 @@ export const LOCK_METAMASK = 'LOCK_METAMASK';
// error handling
export const DISPLAY_WARNING = 'DISPLAY_WARNING';
export const HIDE_WARNING = 'HIDE_WARNING';
export const CAPTURE_SINGLE_EXCEPTION = 'CAPTURE_SINGLE_EXCEPTION';
// accounts screen
export const SHOW_ACCOUNT_DETAIL = 'SHOW_ACCOUNT_DETAIL';
export const SHOW_ACCOUNTS_PAGE = 'SHOW_ACCOUNTS_PAGE';

@ -1,5 +1,6 @@
import pify from 'pify';
import log from 'loglevel';
import { captureException } from '@sentry/browser';
import { capitalize, isEqual } from 'lodash';
import getBuyEthUrl from '../../app/scripts/lib/buy-eth-url';
import {
@ -2715,6 +2716,19 @@ export function setLedgerLivePreference(value) {
};
}
export function captureSingleException(error) {
return async (dispatch, getState) => {
const { singleExceptions } = getState().appState;
if (!(error in singleExceptions)) {
dispatch({
type: actionConstants.CAPTURE_SINGLE_EXCEPTION,
value: error,
});
captureException(Error(error));
}
};
}
// Wrappers around promisifedBackground
/**
* The "actions" below are not actions nor action creators. They cannot use

Loading…
Cancel
Save