diff --git a/src/ReactUnipika/ReactUnipika.tsx b/src/ReactUnipika/ReactUnipika.tsx index 4c8fb08..4fe6460 100644 --- a/src/ReactUnipika/ReactUnipika.tsx +++ b/src/ReactUnipika/ReactUnipika.tsx @@ -25,6 +25,7 @@ export interface ReactUnipikaProps { showContainerSize?: boolean; initiallyCollapsed?: boolean; caseInsensitiveSearch?: boolean; + renderError?: (error: unknown) => React.ReactNode; } const defaultUnipikaSettings = { @@ -51,26 +52,31 @@ export function ReactUnipika({ showContainerSize, initiallyCollapsed, caseInsensitiveSearch, + renderError, }: ReactUnipikaProps) { - const convertedValue = React.useMemo(() => { - // TODO: fix me later - // The call is required because unipika.format() applies default values to a passed settings inplace. - // We have to leave this call without it the behaviour will be broken. - if (settings.format === 'raw-json') { - unipika.formatRaw(value, settings); - } else { - unipika.formatFromYSON(value, settings); - } + const {convertedValue, error} = React.useMemo(() => { + try { + // TODO: fix me later + // The call is required because unipika.format() applies default values to a passed settings inplace. + // We have to leave this call without it the behaviour will be broken. + if (settings.format === 'raw-json') { + unipika.formatRaw(value, settings); + } else { + unipika.formatFromYSON(value, settings); + } - if (value === undefined) { - return ''; - } + if (value === undefined) { + return ''; + } - if (settings.format === 'raw-json') { - return unipika.converters.raw(value, settings); - } + if (settings.format === 'raw-json') { + return unipika.converters.raw(value, settings); + } - return unipika.converters.yson(value, settings); + return {convertedValue: unipika.converters.yson(value, settings)}; + } catch (error) { + return {error}; + } }, [value, settings]); const classes = block( @@ -80,6 +86,10 @@ export function ReactUnipika({ className, ); + if (error) { + return renderError?.(error); + } + function getFormattedTitle() { if (!inline) { return undefined; diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-chromium-1-chromium-linux.png new file mode 100644 index 0000000..45984f4 Binary files /dev/null and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-webkit-1-webkit-linux.png new file mode 100644 index 0000000..00ec5c6 Binary files /dev/null and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-dark-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-chromium-1-chromium-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-chromium-1-chromium-linux.png new file mode 100644 index 0000000..c7bbe92 Binary files /dev/null and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-chromium-1-chromium-linux.png differ diff --git a/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-webkit-1-webkit-linux.png b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-webkit-1-webkit-linux.png new file mode 100644 index 0000000..6fc2d28 Binary files /dev/null and b/src/ReactUnipika/__snapshots__/ReactUnipika.visual.test.tsx-snapshots/ReactUnipika-with-error-light-webkit-1-webkit-linux.png differ diff --git a/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx b/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx index 362da80..eba370a 100644 --- a/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx +++ b/src/ReactUnipika/__stories__/ReactUnipika.stories.tsx @@ -67,3 +67,15 @@ export const WithContainerSizeYson: StoryObj = { showContainerSize: true, }, }; + +export const WithError: StoryObj = { + args: { + value: {val: Infinity}, + renderError: (error: unknown) => { + if (error instanceof Error) { + return
{error.message}
; + } + return 'Unknown error while parsing data'; + }, + }, +}; diff --git a/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx b/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx index 7289c1d..8d730c1 100644 --- a/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx +++ b/src/ReactUnipika/__tests__/ReactUnipika.visual.test.tsx @@ -171,3 +171,9 @@ test('ReactUnipika: search in collapsed - navigate forward', async ({ await expectScreenshot({component: page}); }); + +test('ReactUnipika: with error', async ({mount, expectScreenshot, page}) => { + await mount(, {width: 1280}); + + await expectScreenshot({component: page}); +});