Skip to content

Commit 23519c9

Browse files
authored
feat: render custom error (#27)
* feat: support custom error renderer * fix: test * fix: review
1 parent b0bbea4 commit 23519c9

File tree

7 files changed

+44
-16
lines changed

7 files changed

+44
-16
lines changed

src/ReactUnipika/ReactUnipika.tsx

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface ReactUnipikaProps {
2525
showContainerSize?: boolean;
2626
initiallyCollapsed?: boolean;
2727
caseInsensitiveSearch?: boolean;
28+
renderError?: (error: unknown) => React.ReactNode;
2829
}
2930

3031
const defaultUnipikaSettings = {
@@ -51,26 +52,31 @@ export function ReactUnipika({
5152
showContainerSize,
5253
initiallyCollapsed,
5354
caseInsensitiveSearch,
55+
renderError,
5456
}: ReactUnipikaProps) {
55-
const convertedValue = React.useMemo(() => {
56-
// TODO: fix me later
57-
// The call is required because unipika.format() applies default values to a passed settings inplace.
58-
// We have to leave this call without it the behaviour will be broken.
59-
if (settings.format === 'raw-json') {
60-
unipika.formatRaw(value, settings);
61-
} else {
62-
unipika.formatFromYSON(value, settings);
63-
}
57+
const {convertedValue, error} = React.useMemo(() => {
58+
try {
59+
// TODO: fix me later
60+
// The call is required because unipika.format() applies default values to a passed settings inplace.
61+
// We have to leave this call without it the behaviour will be broken.
62+
if (settings.format === 'raw-json') {
63+
unipika.formatRaw(value, settings);
64+
} else {
65+
unipika.formatFromYSON(value, settings);
66+
}
6467

65-
if (value === undefined) {
66-
return '';
67-
}
68+
if (value === undefined) {
69+
return '';
70+
}
6871

69-
if (settings.format === 'raw-json') {
70-
return unipika.converters.raw(value, settings);
71-
}
72+
if (settings.format === 'raw-json') {
73+
return unipika.converters.raw(value, settings);
74+
}
7275

73-
return unipika.converters.yson(value, settings);
76+
return {convertedValue: unipika.converters.yson(value, settings)};
77+
} catch (error) {
78+
return {error};
79+
}
7480
}, [value, settings]);
7581

7682
const classes = block(
@@ -80,6 +86,10 @@ export function ReactUnipika({
8086
className,
8187
);
8288

89+
if (error) {
90+
return renderError?.(error);
91+
}
92+
8393
function getFormattedTitle() {
8494
if (!inline) {
8595
return undefined;
23.9 KB
Loading
29.9 KB
Loading
Loading
29.8 KB
Loading

src/ReactUnipika/__stories__/ReactUnipika.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,15 @@ export const WithContainerSizeYson: StoryObj<ReactUnipikaProps> = {
6767
showContainerSize: true,
6868
},
6969
};
70+
71+
export const WithError: StoryObj<ReactUnipikaProps> = {
72+
args: {
73+
value: {val: Infinity},
74+
renderError: (error: unknown) => {
75+
if (error instanceof Error) {
76+
return <div>{error.message}</div>;
77+
}
78+
return 'Unknown error while parsing data';
79+
},
80+
},
81+
};

src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,9 @@ test('ReactUnipika: search in collapsed - navigate forward', async ({
171171

172172
await expectScreenshot({component: page});
173173
});
174+
175+
test('ReactUnipika: with error', async ({mount, expectScreenshot, page}) => {
176+
await mount(<Stories.WithError />, {width: 1280});
177+
178+
await expectScreenshot({component: page});
179+
});

0 commit comments

Comments
 (0)