Skip to content

Commit

Permalink
Merge pull request #891 from ensdomains/transaction-error-refactor
Browse files Browse the repository at this point in the history
Clearer naming and ts-pattern
  • Loading branch information
LeonmanRolls authored Oct 3, 2024
2 parents 28b0792 + b894396 commit 7fe385d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { queryOptions } from '@tanstack/react-query'
import { Dispatch, useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import { match, P } from 'ts-pattern'
import { BaseError } from 'viem'
import { useClient, useConnectorClient, useSendTransaction } from 'wagmi'

Expand Down Expand Up @@ -281,7 +282,7 @@ function useCreateSubnameRedirect(
}, [shouldTrigger, subdomain])
}

const getLowerError = ({
const getPreTransactionError = ({
stage,
transactionError,
requestError,
Expand All @@ -290,16 +291,17 @@ const getLowerError = ({
transactionError: Error | null
requestError: Error | null
}) => {
if (stage === 'complete' || stage === 'sent') return null
const err = transactionError || requestError
if (!err) return null
if (!(err instanceof BaseError))
return {
message: 'message' in err ? err.message : 'transaction.error.unknown',
type: 'unknown',
} as const
const readableError = getReadableError(err)
return readableError || ({ message: err.shortMessage, type: 'unknown' } as const)
return match({ stage, err: transactionError || requestError })
.with({ stage: P.union('complete', 'sent') }, () => null)
.with({ err: P.nullish }, () => null)
.with({ err: P.not(P.instanceOf(BaseError)) }, ({ err }) => ({
message: 'message' in err! ? err.message : 'transaction.error.unknown',
type: 'unknown' as const,
}))
.otherwise(({ err }) => {
const readableError = getReadableError(err)
return readableError || { message: (err as BaseError).shortMessage, type: 'unknown' as const }
})
}

export const TransactionStageModal = ({
Expand Down Expand Up @@ -433,13 +435,13 @@ export const TransactionStageModal = ({
queryFn: initialErrorOptions.queryFn,
})

const { data: upperError } = useQuery({
const { data: attemptedTransactionError } = useQuery({
...preparedErrorOptions,
enabled: !!transaction && !!transaction.hash && transactionStatus === 'failed',
})

const lowerError = useMemo(
() => getLowerError({ stage, transactionError, requestError }),
const preTransactionError = useMemo(
() => getPreTransactionError({ stage, transactionError, requestError }),
[stage, transactionError, requestError],
)

Expand Down Expand Up @@ -524,7 +526,7 @@ export const TransactionStageModal = ({
)
}

if (lowerError?.type === 'insufficientFunds')
if (preTransactionError?.type === 'insufficientFunds')
return <Button disabled>{t('transaction.dialog.confirm.insufficientFunds')}</Button>

return (
Expand Down Expand Up @@ -556,23 +558,25 @@ export const TransactionStageModal = ({
transactionLoading,
request,
isTransactionRequestCachedData,
lowerError,
preTransactionError,
])

return (
<>
<Dialog.Heading title={t(`transaction.dialog.${stage}.title`)} />
<Dialog.Content data-testid="transaction-modal-inner">
{MiddleContent}
{upperError && <Helper type="error">{t(upperError.message)}</Helper>}
{attemptedTransactionError && (
<Helper type="error">{t(attemptedTransactionError.message)}</Helper>
)}
{FilledDisplayItems}
{HelperContent}
{transaction.hash && (
<Outlink href={makeEtherscanLink(transaction.hash!, chainName)}>
{t('transaction.viewEtherscan')}
</Outlink>
)}
{lowerError && <Helper type="error">{lowerError.message}</Helper>}
{preTransactionError && <Helper type="error">{preTransactionError.message}</Helper>}
</Dialog.Content>
<Dialog.Footer
currentStep={currentStep}
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/useQueryOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { useAccount, useChainId, useConfig } from 'wagmi'
import { SupportedChain } from '@app/constants/chains'
import { ConfigWithEns, CreateQueryKey, QueryDependencyType } from '@app/types'

/*
Query types:
- independent: Query that is not dependent on chain data, specifically chainId and address
- graph: Query that uses the graph
- standard: Query that depends on chain data directly
*/

export type QueryKeyConfig<
TParams extends {},
TFunctionName extends string,
Expand Down

0 comments on commit 7fe385d

Please sign in to comment.