Skip to content

Commit

Permalink
improve error catching
Browse files Browse the repository at this point in the history
  • Loading branch information
Ben-Rey committed Jul 12, 2024
1 parent 1e904a2 commit ece6332
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 81 deletions.
115 changes: 35 additions & 80 deletions src/lib/massa-react/hooks/useWriteSmartContract.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -14,7 +13,6 @@ import {
Operation,
OperationStatus,
} from '@massalabs/massa-web3';
import { Toast } from 'react-hot-toast';

interface ToasterMessage {
pending: string;
Expand All @@ -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<string | undefined>(undefined);
const success = OperationStatus.SpeculativeSuccess || OperationStatus.Success;

function resetState() {
setIsPending(false);
Expand All @@ -50,7 +49,6 @@ export function useWriteSmartContract(
targetFunction: string,
targetAddress: string,
parameter: Uint8Array,
messages: ToasterMessage,
coins = BigInt(0),
): Promise<bigint> {
try {
Expand All @@ -71,31 +69,6 @@ export function useWriteSmartContract(
}
}

function showToast(
type: 'loading' | 'error' | 'success',
message: string,
operationId?: string,
duration = 5000,
) {
const content = (t: Toast) => (
<ToastContent t={t}>
<OperationToast
isMainnet={isMainnet}
title={message}
operationId={operationId}
/>
</ToastContent>
);

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,
Expand All @@ -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();
}
}
Expand Down
30 changes: 29 additions & 1 deletion src/lib/massa-react/utils.ts → src/lib/massa-react/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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) => (
<ToastContent t={t}>
<OperationToast
isMainnet={isMainnet}
title={message}
operationId={operationId}
/>
</ToastContent>
);

if (type === 'loading') {
return toast.loading(content, { duration: Infinity });
} else if (type === 'error') {
toast.error(content, { duration });
} else {
toast.success(content, { duration });
}
}

0 comments on commit ece6332

Please sign in to comment.