Commit dd445832 authored by tom goriunov's avatar tom goriunov Committed by GitHub

Error is not displayed for functions with no return values. (#2769)

* Error is not displayed for functions with no return values.

Fixes #2749

* fix tests

* update paddings
parent 63978266
...@@ -19,6 +19,7 @@ import ContractMethodFieldAccordion from './ContractMethodFieldAccordion'; ...@@ -19,6 +19,7 @@ import ContractMethodFieldAccordion from './ContractMethodFieldAccordion';
import ContractMethodFieldInput from './ContractMethodFieldInput'; import ContractMethodFieldInput from './ContractMethodFieldInput';
import ContractMethodFieldInputArray from './ContractMethodFieldInputArray'; import ContractMethodFieldInputArray from './ContractMethodFieldInputArray';
import ContractMethodFieldInputTuple from './ContractMethodFieldInputTuple'; import ContractMethodFieldInputTuple from './ContractMethodFieldInputTuple';
import ContractMethodOutput from './ContractMethodOutput';
import ContractMethodResultPublicClient from './ContractMethodResultPublicClient'; import ContractMethodResultPublicClient from './ContractMethodResultPublicClient';
import ContractMethodResultWalletClient from './ContractMethodResultWalletClient'; import ContractMethodResultWalletClient from './ContractMethodResultWalletClient';
import { getFieldLabel, matchArray, transformFormDataToMethodArgs } from './utils'; import { getFieldLabel, matchArray, transformFormDataToMethodArgs } from './utils';
...@@ -236,6 +237,8 @@ const ContractMethodForm = ({ data, attempt, onSubmit, onReset, isOpen }: Props) ...@@ -236,6 +237,8 @@ const ContractMethodForm = ({ data, attempt, onSubmit, onReset, isOpen }: Props)
); );
})(); })();
const showOutputResult = result && result.source === 'public_client' && !(result.data instanceof Error);
return ( return (
<Box> <Box>
<FormProvider { ...formApi }> <FormProvider { ...formApi }>
...@@ -306,12 +309,17 @@ const ContractMethodForm = ({ data, attempt, onSubmit, onReset, isOpen }: Props) ...@@ -306,12 +309,17 @@ const ContractMethodForm = ({ data, attempt, onSubmit, onReset, isOpen }: Props)
onSettle={ handleResultSettle } onSettle={ handleResultSettle }
/> />
) } ) }
{ 'outputs' in data && data.outputs.length > 0 && ( { result && result.source === 'public_client' && result.data instanceof Error && (
<ContractMethodResultPublicClient <ContractMethodResultPublicClient
data={ result && result.source === 'public_client' ? result.data : undefined } data={ result.data }
/>
) }
{ 'outputs' in data && data.outputs.length > 0 && (
<ContractMethodOutput
data={ showOutputResult ? result.data : undefined }
onSettle={ handleResultSettle } onSettle={ handleResultSettle }
abiItem={ data } abiItem={ data }
mode={ result && result.source === 'public_client' ? 'result' : 'preview' } mode={ showOutputResult ? 'result' : 'preview' }
/> />
) } ) }
</Box> </Box>
......
...@@ -3,8 +3,7 @@ import type { AbiFunction } from 'viem'; ...@@ -3,8 +3,7 @@ import type { AbiFunction } from 'viem';
import { test, expect } from 'playwright/lib'; import { test, expect } from 'playwright/lib';
import ContractMethodResultPublicClient from './ContractMethodResultPublicClient'; import ContractMethodOutput from './ContractMethodOutput';
import { ErrorStory } from './ContractMethodResultPublicClient.pwstory';
const abiItem: AbiFunction = { const abiItem: AbiFunction = {
inputs: [], inputs: [],
...@@ -136,7 +135,7 @@ const onSettle = () => {}; ...@@ -136,7 +135,7 @@ const onSettle = () => {};
test('preview mode', async({ render }) => { test('preview mode', async({ render }) => {
const component = await render( const component = await render(
<ContractMethodResultPublicClient <ContractMethodOutput
abiItem={ abiItem } abiItem={ abiItem }
data={ undefined } data={ undefined }
mode="preview" mode="preview"
...@@ -148,7 +147,7 @@ test('preview mode', async({ render }) => { ...@@ -148,7 +147,7 @@ test('preview mode', async({ render }) => {
test('result mode', async({ render }) => { test('result mode', async({ render }) => {
const component = await render( const component = await render(
<ContractMethodResultPublicClient <ContractMethodOutput
abiItem={ abiItem } abiItem={ abiItem }
data={ result } data={ result }
mode="result" mode="result"
...@@ -158,20 +157,9 @@ test('result mode', async({ render }) => { ...@@ -158,20 +157,9 @@ test('result mode', async({ render }) => {
await expect(component).toHaveScreenshot(); await expect(component).toHaveScreenshot();
}); });
test('error', async({ render }) => {
const component = await render(
<ErrorStory
abiItem={ abiItem }
mode="result"
onSettle={ onSettle }
/>,
);
await expect(component).toHaveScreenshot();
});
test('single output', async({ render }) => { test('single output', async({ render }) => {
const component = await render( const component = await render(
<ContractMethodResultPublicClient <ContractMethodOutput
abiItem={{ ...abiItem, outputs: abiItem.outputs.slice(3, 4) }} abiItem={{ ...abiItem, outputs: abiItem.outputs.slice(3, 4) }}
data={ result[3] } data={ result[3] }
mode="result" mode="result"
......
import { Flex } from '@chakra-ui/react';
import React from 'react';
import type { AbiFunction } from 'viem';
import type { ResultViewMode } from '../types';
import ResultItem from './resultPublicClient/Item';
export interface Props {
data: unknown;
abiItem: AbiFunction;
onSettle: () => void;
mode: ResultViewMode;
}
const ContractMethodOutput = ({ data, abiItem, onSettle, mode }: Props) => {
React.useEffect(() => {
if (mode === 'result') {
onSettle();
}
}, [ onSettle, mode ]);
const formattedData = (() => {
return abiItem && abiItem.outputs.length > 1 && Array.isArray(data) ? data : [ data ];
})();
return (
<Flex
flexDir="column"
rowGap={ 2 }
mt={ 3 }
px={ 3 }
py={ 2 }
borderRadius="md"
bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }}
color={ mode === 'preview' ? 'gray.500' : undefined }
fontSize="sm"
lineHeight="20px"
whiteSpace="break-spaces"
wordBreak="break-all"
>
{ abiItem.outputs.map((output, index) => (
<ResultItem
key={ index }
abiParameter={ output }
data={ formattedData[index] }
mode={ mode }
/>
)) }
</Flex>
);
};
export default React.memo(ContractMethodOutput);
import React from 'react';
import type { Props } from './ContractMethodResultPublicClient';
import ContractMethodResultPublicClient from './ContractMethodResultPublicClient';
export const ErrorStory = (props: Omit<Props, 'data'>) => {
const result = new Error('Something went wrong');
return <ContractMethodResultPublicClient { ...props } data={ result }/>;
};
import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import type { AbiFunction } from 'viem';
import type { FormSubmitResultPublicClient, ResultViewMode } from '../types';
import { Alert } from 'toolkit/chakra/alert'; import { Alert } from 'toolkit/chakra/alert';
import ResultItem from './resultPublicClient/Item';
export interface Props { export interface Props {
data: FormSubmitResultPublicClient['data']; data: Error;
abiItem: AbiFunction;
onSettle: () => void;
mode: ResultViewMode;
} }
const ContractMethodResultPublicClient = ({ data, abiItem, onSettle, mode: modeProps }: Props) => { const ContractMethodResultPublicClient = ({ data }: Props) => {
React.useEffect(() => {
if (modeProps === 'result') {
onSettle();
}
}, [ onSettle, modeProps ]);
const formattedData = (() => {
return abiItem.outputs.length > 1 && Array.isArray(data) ? data : [ data ];
})();
const isError = data instanceof Error;
const mode = isError ? 'preview' : modeProps;
return ( return (
<> <Alert status="error" mt={ 3 } textStyle="sm" wordBreak="break-word" whiteSpace="pre-wrap">
{ isError && (
<Alert status="error" mt={ 3 } p={ 4 } borderRadius="md" textStyle="sm" wordBreak="break-word" whiteSpace="pre-wrap">
{ 'shortMessage' in data && typeof data.shortMessage === 'string' ? data.shortMessage : data.message } { 'shortMessage' in data && typeof data.shortMessage === 'string' ? data.shortMessage : data.message }
</Alert> </Alert>
) }
<Flex
flexDir="column"
rowGap={ 2 }
mt={ 3 }
p={ 4 }
borderRadius="md"
bgColor={{ _light: 'blackAlpha.50', _dark: 'whiteAlpha.50' }}
color={ mode === 'preview' ? 'gray.500' : undefined }
fontSize="sm"
lineHeight="20px"
whiteSpace="break-spaces"
wordBreak="break-all"
>
{ abiItem.outputs.map((output, index) => (
<ResultItem
key={ index }
abiParameter={ output }
data={ isError ? undefined : formattedData[index] }
mode={ mode }
/>
)) }
</Flex>
</>
); );
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment