From f008508052248a8ab36534a7545a24c6780622fb Mon Sep 17 00:00:00 2001 From: Gareth Fuller Date: Wed, 5 Jul 2023 09:17:23 +0100 Subject: [PATCH] refactor: Catch all user triggered errors --- .../LockPreviewModal/components/LockActions.vue | 4 ++-- src/composables/swap/useCowswap.ts | 5 ++--- src/composables/swap/useJoinExit.ts | 5 ++--- src/composables/swap/useSor.ts | 5 ++--- src/composables/useTransactionErrors.ts | 8 ++++++-- src/providers/local/join-pool.provider.ts | 4 ++-- .../web3/transactions/concerns/transaction.concern.ts | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/forms/lock_actions/LockForm/components/LockPreviewModal/components/LockActions.vue b/src/components/forms/lock_actions/LockForm/components/LockPreviewModal/components/LockActions.vue index ab59e9ca60..5a6c4b55f3 100644 --- a/src/components/forms/lock_actions/LockForm/components/LockPreviewModal/components/LockActions.vue +++ b/src/components/forms/lock_actions/LockForm/components/LockPreviewModal/components/LockActions.vue @@ -24,7 +24,7 @@ import { VeBalLockInfo } from '@/services/balancer/contracts/contracts/veBAL'; import { ApprovalAction } from '@/composables/approvals/types'; import { captureException } from '@sentry/browser'; import useTokenApprovalActions from '@/composables/approvals/useTokenApprovalActions'; -import { isUserRejected } from '@/composables/useTransactionErrors'; +import { isUserError } from '@/composables/useTransactionErrors'; /** * TYPES @@ -188,7 +188,7 @@ async function submit(lockType: LockType, actionIndex: number) { // An exception is already logged in balancerContractsService, but we should // log another here in case any exceptions are thrown before it's sent - if (!isUserRejected(error)) { + if (!isUserError(error)) { captureException(error, { level: 'fatal', extra: { diff --git a/src/composables/swap/useCowswap.ts b/src/composables/swap/useCowswap.ts index f81a7ce9ec..18260a9cc3 100644 --- a/src/composables/swap/useCowswap.ts +++ b/src/composables/swap/useCowswap.ts @@ -21,7 +21,7 @@ import useTransactions from '../useTransactions'; import { SwapQuote } from './types'; import { captureException } from '@sentry/browser'; import { Goals, trackGoal } from '../useFathom'; -import useTransactionErrors from '../useTransactionErrors'; +import { isUserError } from '../useTransactionErrors'; import { useI18n } from 'vue-i18n'; import { useApp } from '@/composables/useApp'; @@ -93,7 +93,6 @@ export default function useCowswap({ const { addTransaction } = useTransactions(); const { fNum } = useNumbers(); const { balanceFor } = useTokens(); - const { isUserRejected } = useTransactionErrors(); const { t } = useI18n(); // DATA @@ -238,7 +237,7 @@ export default function useCowswap({ confirming.value = false; trackGoal(Goals.CowswapSwap); } catch (error) { - if (!isUserRejected(error)) { + if (!isUserError(error)) { console.trace(error); state.submissionError = t('swapException', ['Cowswap']); captureException(new Error(state.submissionError, { cause: error }), { diff --git a/src/composables/swap/useJoinExit.ts b/src/composables/swap/useJoinExit.ts index d1d43488c8..587ef7ef67 100644 --- a/src/composables/swap/useJoinExit.ts +++ b/src/composables/swap/useJoinExit.ts @@ -28,7 +28,7 @@ import useEthers from '../useEthers'; import useRelayerApprovalQuery from '@/composables/queries/useRelayerApprovalQuery'; import { TransactionBuilder } from '@/services/web3/transactions/transaction.builder'; import BatchRelayerAbi from '@/lib/abi/BatchRelayer.json'; -import useTransactionErrors from '../useTransactionErrors'; +import { isUserError } from '../useTransactionErrors'; import { useI18n } from 'vue-i18n'; type JoinExitState = { @@ -91,7 +91,6 @@ export default function useJoinExit({ const { addTransaction } = useTransactions(); const { txListener } = useEthers(); const { fNum } = useNumbers(); - const { isUserRejected } = useTransactionErrors(); const { t } = useI18n(); const hasValidationError = computed( @@ -237,7 +236,7 @@ export default function useJoinExit({ }, }); } catch (error) { - if (!isUserRejected(error)) { + if (!isUserError(error)) { console.trace(error); state.submissionError = t('swapException', ['Relayer']); captureException(new Error(state.submissionError, { cause: error }), { diff --git a/src/composables/swap/useSor.ts b/src/composables/swap/useSor.ts index 7feb6dbbf0..22ebdb4fba 100644 --- a/src/composables/swap/useSor.ts +++ b/src/composables/swap/useSor.ts @@ -43,7 +43,7 @@ import useTransactions, { TransactionAction } from '../useTransactions'; import { SwapQuote } from './types'; import { captureException } from '@sentry/browser'; import { overflowProtected } from '@/components/_global/BalTextInput/helpers'; -import useTransactionErrors from '../useTransactionErrors'; +import { isUserError } from '../useTransactionErrors'; type SorState = { validationErrors: { @@ -204,7 +204,6 @@ export default function useSor({ const { fNum, toFiat } = useNumbers(); const { t } = useI18n(); const { injectTokens, priceFor, getToken } = useTokens(); - const { isUserRejected } = useTransactionErrors(); const { swapIn, swapOut } = useSwapper(); onMounted(async () => { @@ -799,7 +798,7 @@ export default function useSor({ } function handleSwapException(error: Error) { - if (!isUserRejected(error)) { + if (!isUserError(error)) { console.trace(error); state.submissionError = t('swapException', ['Balancer']); captureException(new Error(state.submissionError, { cause: error })); diff --git a/src/composables/useTransactionErrors.ts b/src/composables/useTransactionErrors.ts index f7fd128aeb..ac28f33d16 100644 --- a/src/composables/useTransactionErrors.ts +++ b/src/composables/useTransactionErrors.ts @@ -71,6 +71,11 @@ function isErrorType(error, messages: RegExp[]): boolean { return false; } +// Errors that are caused by the user or the state of their wallet. +export function isUserError(error): boolean { + return isUserRejected(error) || isUserNotEnoughGas(error); +} + export default function useTransactionErrors() { /** * COMPOSABLES @@ -106,8 +111,7 @@ export default function useTransactionErrors() { * METHODS */ function parseError(error): TransactionError | null { - if (isUserRejected(error)) return null; // User rejected transaction - if (isUserNotEnoughGas(error)) return null; // User does not have enough gas + if (isUserError(error)) return null; if (error?.code && error.code === 'UNPREDICTABLE_GAS_LIMIT') return cannotEstimateGasError; diff --git a/src/providers/local/join-pool.provider.ts b/src/providers/local/join-pool.provider.ts index f28b2cd2e6..9efe766528 100644 --- a/src/providers/local/join-pool.provider.ts +++ b/src/providers/local/join-pool.provider.ts @@ -49,7 +49,7 @@ import useTokenApprovalActions from '@/composables/approvals/useTokenApprovalAct import { useApp } from '@/composables/useApp'; import { throwQueryError } from '@/lib/utils/queries'; import { ApprovalAction } from '@/composables/approvals/types'; -import { isUserRejected } from '@/composables/useTransactionErrors'; +import { isUserError } from '@/composables/useTransactionErrors'; /** * TYPES @@ -376,7 +376,7 @@ export const joinPoolProvider = ( } async function logJoinException(error: Error) { - if (isUserRejected(error)) return; + if (isUserError(error)) return; const sender = await getSigner().getAddress(); captureException(error, { diff --git a/src/services/web3/transactions/concerns/transaction.concern.ts b/src/services/web3/transactions/concerns/transaction.concern.ts index 65240c82a1..c13fd8d82d 100644 --- a/src/services/web3/transactions/concerns/transaction.concern.ts +++ b/src/services/web3/transactions/concerns/transaction.concern.ts @@ -1,4 +1,4 @@ -import { isUserRejected } from '@/composables/useTransactionErrors'; +import { isUserError } from '@/composables/useTransactionErrors'; import { configService } from '@/services/config/config.service'; import { gasService } from '@/services/gas/gas.service'; import { rpcProviderService } from '@/services/rpc-provider/rpc-provider.service'; @@ -11,6 +11,6 @@ export class TransactionConcern { ) {} public shouldLogFailure(error): boolean { - return this.config.env.APP_ENV !== 'development' && !isUserRejected(error); + return this.config.env.APP_ENV !== 'development' && !isUserError(error); } }