From ece63320cfd2e7b79ebeccdfe51a5fd3a6620c72 Mon Sep 17 00:00:00 2001 From: BenRey Date: Fri, 12 Jul 2024 05:13:53 +0200 Subject: [PATCH] improve error catching --- .../hooks/useWriteSmartContract.tsx | 115 ++++++------------ src/lib/massa-react/{utils.ts => utils.tsx} | 30 ++++- 2 files changed, 64 insertions(+), 81 deletions(-) rename src/lib/massa-react/{utils.ts => utils.tsx} (70%) diff --git a/src/lib/massa-react/hooks/useWriteSmartContract.tsx b/src/lib/massa-react/hooks/useWriteSmartContract.tsx index edf4c563..55417c6d 100644 --- a/src/lib/massa-react/hooks/useWriteSmartContract.tsx +++ b/src/lib/massa-react/hooks/useWriteSmartContract.tsx @@ -1,7 +1,6 @@ import { useState } from 'react'; -import { toast, ToastContent } from '../../../components'; -import { OperationToast } from '../../ConnectMassaWallets/components/OperationToast'; -import { logSmartContractEvents } from '../utils'; +import { toast } from '../../../components'; +import { logSmartContractEvents, showToast } from '../utils'; import Intl from '../i18n'; import { IAccount, @@ -14,7 +13,6 @@ import { Operation, OperationStatus, } from '@massalabs/massa-web3'; -import { Toast } from 'react-hot-toast'; interface ToasterMessage { pending: string; @@ -30,13 +28,14 @@ function minBigInt(a: bigint, b: bigint) { export function useWriteSmartContract( account: IAccount, provider: IProvider, - isMainnet?: boolean, + isMainnet = false, ) { const [isPending, setIsPending] = useState(false); const [isOpPending, setIsOpPending] = useState(false); const [isSuccess, setIsSuccess] = useState(false); const [isError, setIsError] = useState(false); const [opId, setOpId] = useState(undefined); + const success = OperationStatus.SpeculativeSuccess || OperationStatus.Success; function resetState() { setIsPending(false); @@ -50,7 +49,6 @@ export function useWriteSmartContract( targetFunction: string, targetAddress: string, parameter: Uint8Array, - messages: ToasterMessage, coins = BigInt(0), ): Promise { try { @@ -71,31 +69,6 @@ export function useWriteSmartContract( } } - function showToast( - type: 'loading' | 'error' | 'success', - message: string, - operationId?: string, - duration = 5000, - ) { - const content = (t: Toast) => ( - - - - ); - - if (type === 'loading') { - return toast.loading(content, { duration: Infinity }); - } else if (type === 'error') { - toast.error(content, { duration }); - } else { - toast.success(content, { duration }); - } - } - async function callSmartContract( targetFunction: string, targetAddress: string, @@ -112,71 +85,53 @@ export function useWriteSmartContract( try { const publicClient = new JsonRPCClient(await provider.getNetwork()); - let maxGas: bigint; - try { - maxGas = await gasEstimation( - targetFunction, - targetAddress, - parameter, - coins, - ); - } catch (error) { - console.error('Gas estimation failed:', error); - showToast('error', messages.error); - return; - } + let maxGas = await gasEstimation( + targetFunction, + targetAddress, + parameter, + coins, + ); - let operationId: string; - try { - const { operationId: opId } = (await account.callSC( - targetAddress, - targetFunction, - new Uint8Array(parameter), - coins, - 0n, - maxGas, - )) as ITransactionDetails; - operationId = opId; - setOpId(operationId); - setIsOpPending(true); - } catch (error) { - console.error('Smart contract call failed:', error); - showToast('error', 'Smart contract call failed.'); - return; - } + const { operationId } = (await account.callSC( + targetAddress, + targetFunction, + new Uint8Array(parameter), + coins, + 0n, + maxGas, + )) as ITransactionDetails; + + setOpId(operationId); + setIsOpPending(true); - loadingToastId = showToast('loading', messages.pending, operationId); - - try { - const op = new Operation(publicClient, operationId); - const finalStatus = await op.waitFinalExecution(); - if (finalStatus !== OperationStatus.Success) { - const errorMessage = `Operation failed with status: ${finalStatus}`; - console.error(errorMessage); - showToast('error', messages.error, operationId); - logSmartContractEvents(publicClient, operationId); - throw new Error(errorMessage); - } - } catch (error) { - console.error('Operation execution failed:', error); - showToast('error', messages.error, operationId); + loadingToastId = showToast( + 'loading', + messages.pending, + operationId, + isMainnet, + ); + + const op = new Operation(publicClient, operationId); + const finalStatus = await op.waitSpeculativeExecution(); + + if (!success) { + const errorMessage = `Operation failed with status: ${finalStatus}`; logSmartContractEvents(publicClient, operationId); - return; + throw new Error(errorMessage); } setIsSuccess(true); - toast.dismiss(loadingToastId); showToast('success', messages.success, operationId); } catch (error) { console.error('Error during smart contract call:', error); setIsError(true); - toast.dismiss(loadingToastId); showToast( 'error', messages.timeout || Intl.t('steps.failed-timeout'), opId, ); } finally { + toast.dismiss(loadingToastId); resetState(); } } diff --git a/src/lib/massa-react/utils.ts b/src/lib/massa-react/utils.tsx similarity index 70% rename from src/lib/massa-react/utils.ts rename to src/lib/massa-react/utils.tsx index 8d673c43..da748c7d 100644 --- a/src/lib/massa-react/utils.ts +++ b/src/lib/massa-react/utils.tsx @@ -6,9 +6,11 @@ import { MASSA_EXPLORER_URL, } from './const'; import Intl from './i18n'; -import { toast } from '../../components'; +import { toast, ToastContent } from '../../components'; import { Operation, PublicAPI } from '@massalabs/massa-web3'; +import { Toast } from 'react-hot-toast'; +import { OperationToast } from '../ConnectMassaWallets/components/OperationToast'; export async function logSmartContractEvents( client: PublicAPI, @@ -62,3 +64,29 @@ export async function fetchMASBalance( return { finalBalance: '0', candidateBalance: '0' }; } } + +export function showToast( + type: 'loading' | 'error' | 'success', + message: string, + operationId?: string, + isMainnet?: boolean, + duration = 5000, +) { + const content = (t: Toast) => ( + + + + ); + + if (type === 'loading') { + return toast.loading(content, { duration: Infinity }); + } else if (type === 'error') { + toast.error(content, { duration }); + } else { + toast.success(content, { duration }); + } +}