Skip to content

Commit

Permalink
refactor: handle rejected tx & messages (#2172)
Browse files Browse the repository at this point in the history
  • Loading branch information
namgold authored Aug 15, 2023
1 parent 2f0fdfd commit 2683215
Show file tree
Hide file tree
Showing 25 changed files with 187 additions and 157 deletions.
10 changes: 4 additions & 6 deletions src/components/SwapForm/AddMEVProtectionModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChainId } from '@kyberswap/ks-sdk-core'
import { Trans, t } from '@lingui/macro'
import { Connector } from '@web3-react/types'
import { darken } from 'polished'
import { useCallback, useState } from 'react'
import { X } from 'react-feather'
Expand All @@ -14,12 +13,12 @@ import { NotificationType } from 'components/Announcement/type'
import { ButtonEmpty, ButtonOutlined, ButtonPrimary } from 'components/Button'
import Modal from 'components/Modal'
import Row, { RowBetween } from 'components/Row'
import { didUserReject } from 'constants/connectors/utils'
import { Z_INDEXS } from 'constants/styles'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
import { useChangeNetwork } from 'hooks/web3/useChangeNetwork'
import { useNotify } from 'state/application/hooks'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { friendlyError } from 'utils/errorMessage'

const Wrapper = styled.div`
padding: 20px;
Expand Down Expand Up @@ -113,10 +112,9 @@ export default function AddMEVProtectionModal({ isOpen, onClose }: { isOpen: boo
onClose?.()
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'success' })
},
(connector: Connector, error: Error) => {
let reason = error?.message || 'Unknown reason'
if (didUserReject(connector, error)) reason = 'User rejected'
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'fail', reason })
(error: Error) => {
const message = friendlyError(error)
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'fail', reason: message })
},
)
}, [addNewNetwork, notify, onClose, selectedOption, mixpanelHandler])
Expand Down
8 changes: 4 additions & 4 deletions src/components/SwapForm/SwapModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Props = {
const SwapModal: React.FC<Props> = props => {
const { isOpen, tokenAddToMetaMask, onDismiss, swapCallback, buildResult, isBuildingRoute } = props
const { chainId, account } = useActiveWeb3React()

const dispatch = useDispatch()
// modal and loading
const [{ error, isAttemptingTx, txHash }, setSwapState] = useState<{
Expand All @@ -48,7 +49,7 @@ const SwapModal: React.FC<Props> = props => {

const amountOut = currencyOut && CurrencyAmount.fromRawAmount(currencyOut, buildResult?.data?.amountOut || '0')
// text to show while loading
const pendingText = `Swapping ${routeSummary?.parsedAmountIn?.toSignificant(6)} ${
const pendingText = t`Swapping ${routeSummary?.parsedAmountIn?.toSignificant(6)} ${
currencyIn?.symbol
} for ${amountOut?.toSignificant(6)} ${currencyOut?.symbol}`

Expand Down Expand Up @@ -107,9 +108,8 @@ const SwapModal: React.FC<Props> = props => {
const hash = await swapCallback()
handleTxSubmitted(hash)
} catch (e) {
if (e?.code !== 4001 && e?.code !== 'ACTION_REJECTED') captureSwapError(e)
const msg = t`Something went wrong. Please try again`
handleError(e.message === '[object Object]' ? msg : e.message || msg)
captureSwapError(e)
handleError(e.message)
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/TransactionConfirmationModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { VIEW_MODE } from 'state/user/reducer'
import { ExternalLink } from 'theme'
import { CloseIcon } from 'theme/components'
import { getEtherscanLink, getTokenLogoURL } from 'utils'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'

const Wrapper = styled.div`
width: 100%;
Expand Down Expand Up @@ -280,9 +280,9 @@ export function TransactionErrorContent({
lineHeight={'24px'}
style={{ textAlign: 'center', width: '85%' }}
>
{errorFriendly(message)}
{friendlyError(message)}
</Text>
{message !== errorFriendly(message) && (
{message !== friendlyError(message) && (
<AutoColumn justify="center" style={{ width: '100%' }}>
<Text
color={theme.primary}
Expand Down
4 changes: 2 additions & 2 deletions src/components/WalletPopup/SendToken/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useCurrencyBalance } from 'state/wallet/hooks'
import { useCheckAddressSolana } from 'state/wallet/solanaHooks'
import { TransactionFlowState } from 'types/TransactionFlowState'
import { formattedNum, shortenAddress } from 'utils'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'
import { maxAmountSpend } from 'utils/maxAmountSpend'

const Label = styled.label<{ color?: string }>`
Expand Down Expand Up @@ -142,7 +142,7 @@ export default function SendToken({
setFlowState(state => ({
...state,
attemptingTxn: false,
errorMessage: errorFriendly(error?.message ?? 'Error occur, please try again'),
errorMessage: friendlyError(error),
}))
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/swapv2/LimitOrder/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export const calcPercentFilledOrder = (value: string, total: string, decimals: n
}
}

// todo: move to friendlyError
export const getErrorMessage = (error: any) => {
console.error('Limit order error: ', error)
const errorCode: string = error?.response?.data?.code || error.code || ''
Expand Down
6 changes: 3 additions & 3 deletions src/components/swapv2/styleds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AutoColumn } from 'components/Column'
import Modal, { ModalProps } from 'components/Modal'
import { Z_INDEXS } from 'constants/styles'
import useTheme from 'hooks/useTheme'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'

export const PageWrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -136,9 +136,9 @@ export function SwapCallbackError({ error, style = {} }: { error: string; style?
<Alert style={{ marginBottom: 'auto' }} />
<AutoColumn style={{ flexBasis: '100%', margin: '10px 0 auto 8px' }}>
<Text fontSize="16px" fontWeight="500" color={theme.red} lineHeight={'24px'}>
{errorFriendly(error)}
{friendlyError(error)}
</Text>
{error !== errorFriendly(error) && (
{error !== friendlyError(error) && (
<Text
color={theme.primary}
fontSize="12px"
Expand Down
24 changes: 12 additions & 12 deletions src/constants/connectors/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { Connector } from '@web3-react/types'

import { coinbaseWallet, walletConnectV2 } from 'constants/connectors/evm'
import checkForBraveBrowser from 'utils/checkForBraveBrowser'

export const getIsInjected = () => Boolean(window.ethereum)
Expand Down Expand Up @@ -51,21 +48,24 @@ export enum ErrorCode {
MM_ALREADY_PENDING = -32002,

ACTION_REJECTED = 'ACTION_REJECTED',
WC_MODAL_CLOSED = 'Error: User closed modal',
CB_REJECTED_REQUEST = 'Error: User denied account authorization',
ALPHA_WALLET_USER_REJECTED_REQUEST = -32050,
WALLETCONNECT_MODAL_CLOSED = 'Error: User closed modal',
WALLETCONNECT_CANCELED = 'The transaction was cancelled',
COINBASE_REJECTED_REQUEST = 'Error: User denied account authorization',
ALPHA_WALLET_REJECTED_CODE = -32050,
ALPHA_WALLET_REJECTED = 'Request rejected',
CANCELED = 'The transaction was cancelled',
}

export function didUserReject(connector: Connector, error: any): boolean {
const rejectedPhrases: string[] = ['user rejected transaction', 'user denied transaction', 'you must accept']

export function didUserReject(error: any): boolean {
return (
error?.code === ErrorCode.USER_REJECTED_REQUEST ||
error?.code === ErrorCode.ACTION_REJECTED ||
error?.code === ErrorCode.ALPHA_WALLET_USER_REJECTED_REQUEST ||
error?.code === ErrorCode.ALPHA_WALLET_REJECTED_CODE ||
error?.message === ErrorCode.ALPHA_WALLET_REJECTED ||
(connector === walletConnectV2 && error?.toString?.() === ErrorCode.WC_MODAL_CLOSED) ||
(connector === walletConnectV2 && error?.message === ErrorCode.CANCELED) ||
(connector === coinbaseWallet && error?.toString?.() === ErrorCode.CB_REJECTED_REQUEST)
error?.message === ErrorCode.WALLETCONNECT_MODAL_CLOSED ||
error?.message === ErrorCode.WALLETCONNECT_CANCELED ||
error?.message === ErrorCode.WALLETCONNECT_MODAL_CLOSED ||
rejectedPhrases.some(phrase => error?.message?.toLowerCase?.()?.includes?.(phrase.toLowerCase()))
)
}
45 changes: 18 additions & 27 deletions src/hooks/kyberdao/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { useTransactionAdder } from 'state/transactions/hooks'
import { TRANSACTION_TYPE } from 'state/transactions/type'
import { calculateGasMargin } from 'utils'
import { aggregateValue } from 'utils/array'
import { formatWalletErrorMessage } from 'utils/errorMessage'
import { friendlyError } from 'utils/errorMessage'
import { formatUnitsToFixed } from 'utils/formatBalance'
import { sendEVMTransaction } from 'utils/sendTransaction'

Expand Down Expand Up @@ -89,7 +89,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -120,7 +120,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -155,7 +155,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand All @@ -181,7 +181,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand All @@ -208,7 +208,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -272,7 +272,7 @@ export function useClaimVotingRewards() {
})
return tx.hash as string
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -312,7 +312,7 @@ export const useVotingActions = () => {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -620,7 +620,7 @@ export function useGasRefundInfo({ rewardStatus = KNCUtilityTabs.Available }: {

export function useClaimGasRefundRewards() {
const { account, chainId } = useActiveWeb3React()
const { library, connector } = useWeb3React()
const { library } = useWeb3React()
const addTransactionWithType = useTransactionAdder()
const { claimableReward } = useGasRefundInfo({})
const refetch = useRefetchGasRefundInfo()
Expand Down Expand Up @@ -669,25 +669,16 @@ export function useClaimGasRefundRewards() {
return tx.hash as string
} catch (error) {
refetch()
if (didUserReject(connector, error)) {
notify({
title: t`Transaction rejected`,
summary: t`In order to claim, you must accept in your wallet.`,
type: NotificationType.ERROR,
})
throw new Error('Transaction rejected.')
} else {
const message = formatWalletErrorMessage(error)
console.error('Claim error:', { error, message })
notify({
title: t`Claim Error`,
summary: message,
type: NotificationType.ERROR,
})
throw error
}
const message = friendlyError(error)
console.error('Claim error:', { message, error })
notify({
title: t`Claim Error`,
summary: message,
type: NotificationType.ERROR,
})
throw error
}
}, [account, addTransactionWithType, chainId, claimableReward, library, notify, connector, refetch])
}, [account, addTransactionWithType, chainId, claimableReward, library, notify, refetch])
return claimGasRefundRewards
}

Expand Down
18 changes: 16 additions & 2 deletions src/hooks/useApproveCallback.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { MaxUint256 } from '@ethersproject/constants'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, CurrencyAmount, TokenAmount } from '@kyberswap/ks-sdk-core'
import { t } from '@lingui/macro'
import JSBI from 'jsbi'
import { useCallback, useMemo } from 'react'

import { NotificationType } from 'components/Announcement/type'
import { useTokenAllowance } from 'data/Allowances'
import { useNotify } from 'state/application/hooks'
import { Field } from 'state/swap/actions'
import { useHasPendingApproval, useTransactionAdder } from 'state/transactions/hooks'
import { TRANSACTION_TYPE } from 'state/transactions/type'
import { calculateGasMargin } from 'utils'
import { Aggregator } from 'utils/aggregator'
import { friendlyError } from 'utils/errorMessage'
import { computeSlippageAdjustedAmounts } from 'utils/prices'

import { useActiveWeb3React } from './index'
Expand Down Expand Up @@ -55,6 +59,7 @@ export function useApproveCallback(
: ApprovalState.NOT_APPROVED
: ApprovalState.APPROVED
}, [amountToApprove, currentAllowance, isSolana, pendingApproval, spender])
const notify = useNotify()

const tokenContract = useTokenContract(token?.address)
const addTransactionWithType = useTransactionAdder()
Expand Down Expand Up @@ -123,11 +128,20 @@ export function useApproveCallback(
})
})
.catch((error: Error) => {
console.debug('Failed to approve token', error)
const message = friendlyError(error)
console.error('Approve token error:', { message, error })
notify(
{
title: t`Approve Error`,
summary: message,
type: NotificationType.ERROR,
},
8000,
)
throw error
})
},
[approvalState, token, tokenContract, amountToApprove, spender, addTransactionWithType, forceApprove],
[approvalState, token, tokenContract, amountToApprove, spender, addTransactionWithType, forceApprove, notify],
)

return [approvalState, approve, currentAllowance]
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useElasticLegacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import JSBI from 'jsbi'
import { useEffect, useRef, useState } from 'react'

import TickReaderABI from 'constants/abis/v2/ProAmmTickReader.json'
import { didUserReject } from 'constants/connectors/utils'
import { EVMNetworkInfo } from 'constants/networks/type'
import { useActiveWeb3React, useWeb3React } from 'hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
Expand Down Expand Up @@ -464,7 +465,7 @@ export const useRemoveLiquidityLegacy = (
setShowPendingModal('removeLiquidity')
setAttemptingTxn(false)

if (error?.code !== 'ACTION_REJECTED') {
if (!didUserReject(error)) {
const e = new Error('Remove Legacy Elastic Liquidity Error', { cause: error })
e.name = ErrorName.RemoveElasticLiquidityError
captureException(e, {
Expand Down
Loading

0 comments on commit 2683215

Please sign in to comment.