properly handle submit errors

This commit is contained in:
fernandomg 2020-05-29 21:45:22 -03:00
parent df0562911e
commit 45bbbc9967
2 changed files with 45 additions and 21 deletions

View File

@ -17,8 +17,15 @@ const Buttons = ({ onCallSubmit, onClose }) => {
const { const {
input: { value: contractAddress }, input: { value: contractAddress },
} = useField('contractAddress', { valid: true } as any) } = useField('contractAddress', { valid: true } as any)
const { submitting, valid, validating, values } = useFormState({ const { modifiedSinceLastSubmit, submitError, submitting, valid, validating, values } = useFormState({
subscription: { submitting: true, valid: true, values: true, validating: true }, subscription: {
modifiedSinceLastSubmit: true,
submitError: true,
submitting: true,
valid: true,
values: true,
validating: true,
},
}) })
const handleCallSubmit = async () => { const handleCallSubmit = async () => {
@ -48,7 +55,13 @@ const Buttons = ({ onCallSubmit, onClose }) => {
className={classes.submitButton} className={classes.submitButton}
color="primary" color="primary"
data-testid="review-tx-btn" data-testid="review-tx-btn"
disabled={submitting || validating || !valid || !method || (method as any).action === 'read'} disabled={
submitting ||
validating ||
((!valid || !!submitError) && !modifiedSinceLastSubmit) ||
!method ||
(method as any).action === 'read'
}
minWidth={140} minWidth={140}
type="submit" type="submit"
variant="contained" variant="contained"

View File

@ -1,26 +1,23 @@
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import { FORM_ERROR } from 'final-form'
import React from 'react' import React from 'react'
import { styles } from './style' import { styles } from './style'
import GnoForm from 'src/components/forms/GnoForm' import GnoForm from 'src/components/forms/GnoForm'
import Block from 'src/components/layout/Block' import Block from 'src/components/layout/Block'
import Hairline from 'src/components/layout/Hairline' import Hairline from 'src/components/layout/Hairline'
import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo' import SafeInfo from 'src/routes/safe/components/Balances/SendModal/SafeInfo'
import Buttons from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Buttons' import Buttons from './Buttons'
import ContractABI from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/ContractABI' import ContractABI from './ContractABI'
import EthAddressInput from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthAddressInput' import EthAddressInput from './EthAddressInput'
import EthValue from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/EthValue' import EthValue from './EthValue'
import FormDivisor from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/FormDivisor' import FormDivisor from './FormDivisor'
import Header from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/Header' import FormErrorMessage from './FormErrorMessage'
import MethodsDropdown from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/MethodsDropdown' import Header from './Header'
import RenderInputParams from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderInputParams' import MethodsDropdown from './MethodsDropdown'
import RenderOutputParams from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/RenderOutputParams' import RenderInputParams from './RenderInputParams'
import { import RenderOutputParams from './RenderOutputParams'
abiExtractor, import { abiExtractor, createTxObject, formMutators } from './utils'
createTxObject,
formMutators,
} from 'src/routes/safe/components/Balances/SendModal/screens/ContractInteraction/utils'
const useStyles = makeStyles(styles as any) const useStyles = makeStyles(styles as any)
@ -35,8 +32,21 @@ const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }
const handleSubmit = async ({ contractAddress, selectedMethod, value, ...values }) => { const handleSubmit = async ({ contractAddress, selectedMethod, value, ...values }) => {
if (value || (contractAddress && selectedMethod)) { if (value || (contractAddress && selectedMethod)) {
const data = await createTxObject(selectedMethod, contractAddress, values).encodeABI() try {
const txObject = createTxObject(selectedMethod, contractAddress, values)
const data = txObject.encodeABI()
await txObject.estimateGas()
onNext({ contractAddress, data, selectedMethod, value, ...values }) onNext({ contractAddress, data, selectedMethod, value, ...values })
} catch (e) {
for (const key in values) {
if (values.hasOwnProperty(key) && values[key] === e.value) {
return { [key]: e.reason }
}
}
// .estimateGas() failed
return { [FORM_ERROR]: e.message }
}
} }
} }
@ -62,11 +72,12 @@ const ContractInteraction = ({ contractAddress, initialValues, onClose, onNext }
onScannedValue={mutators.setContractAddress} onScannedValue={mutators.setContractAddress}
text="Contract Address*" text="Contract Address*"
/> />
<EthValue onSetMax={mutators.setMax} />
<ContractABI /> <ContractABI />
<MethodsDropdown onChange={mutators.setSelectedMethod} /> <MethodsDropdown onChange={mutators.setSelectedMethod} />
<EthValue onSetMax={mutators.setMax} />
<RenderInputParams /> <RenderInputParams />
<RenderOutputParams /> <RenderOutputParams />
<FormErrorMessage />
</Block> </Block>
<Hairline /> <Hairline />
<Buttons onCallSubmit={mutators.setCallResults} onClose={onClose} /> <Buttons onCallSubmit={mutators.setCallResults} onClose={onClose} />