Error Handling
Handle errors, manage fees, and dispose of sensitive data in EVM wallets.
This guide covers best practices for handling transaction errors, managing fee limits, and cleaning up sensitive data from memory.
Handle Transaction Errors
Wrap transactions in try/catch blocks to handle common failure scenarios such as insufficient funds or exceeded fee limits.
import {
MaximumFeeExceededError,
ProviderRequiredError,
ValueError
} from '@tetherto/wdk-wallet'
try {
const result = await account.sendTransaction({
to: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
value: 1000000000000000000n
})
console.log('Transaction submitted:', result.hash)
} catch (error) {
if (error instanceof ProviderRequiredError) {
console.log('Connect the account to a provider before sending')
} else if (error instanceof MaximumFeeExceededError) {
console.log('Transaction fee too high')
} else if (error instanceof ValueError) {
console.log('Review the transaction type and fee fields')
} else {
throw error
}
}Handle Token Transfer Errors
Token transfers can fail for additional reasons such as invalid addresses or insufficient token balances.
import {
MaximumFeeExceededError,
ProviderRequiredError
} from '@tetherto/wdk-wallet'
try {
const result = await account.transfer({
token: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDt
recipient: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
amount: 1000000000000000000n
})
console.log('Transfer submitted:', result.hash)
} catch (error) {
if (error instanceof ProviderRequiredError) {
console.log('Connect the account to a provider before transferring')
} else if (error instanceof MaximumFeeExceededError) {
console.log('Transfer fee too high')
} else {
throw error
}
}Resolution means the provider accepted the broadcast; it does not prove inclusion or successful EVM execution. Pass the returned hash to waitForTransaction(), then inspect finality and success before releasing goods or updating durable application state.
Manage Fee Limits
Set transactionMaxFee to cap native sendTransaction() costs and provider-backed signTransaction() costs. Offline signing without a provider cannot estimate fees, so the fee-cap check does not run there. Set transferMaxFee separately to cap ERC-20 transfer() costs. Retrieve current network rates with getFeeRates() to make informed decisions.
const feeRates = await wallet.getFeeRates()
console.log('Normal fee rate:', feeRates.normal, 'wei')
console.log('Fast fee rate:', feeRates.fast, 'wei')Handle Transaction Status Errors
getTransaction() throws ValueError for a malformed 32-byte hash and NoSuchElementError when neither a transaction nor receipt can be found. waitForTransaction() throws TimeoutError if it does not reach the requested finality within the configured time. A returned dropped receipt is not an exception; it means the sender's mined nonce advanced beyond the pending transaction's nonce.
Do not treat finality as execution success. A mined EVM transaction can be confirmed or final with success: false when it reverted.
Handle Non-derivable Signers
In 1.0.0-beta.18, PrivateKeySignerEvm.derive() throws InvalidSignerError from @tetherto/wdk-wallet. The package also uses this error when a non-derivable signer is supplied as the wallet manager's default signer.
import { InvalidSignerError } from '@tetherto/wdk-wallet'
try {
await privateKeySigner.derive("0'/0/1")
} catch (error) {
if (error instanceof InvalidSignerError) {
console.error('Register this private-key signer by name instead of deriving it')
} else {
throw error
}
}Dispose of Sensitive Data
Call dispose() on accounts and wallet managers to clear private keys and sensitive data from memory when they are no longer needed.
account.dispose()
wallet.dispose()Always call dispose() in a finally block or cleanup handler to ensure sensitive data is cleared even if an error occurs.