diff --git a/web/app/(commonLayout)/error.tsx b/web/app/(commonLayout)/error.tsx index 26400fc1fb9..9128c73cdd2 100644 --- a/web/app/(commonLayout)/error.tsx +++ b/web/app/(commonLayout)/error.tsx @@ -8,12 +8,12 @@ import { isLegacyBase401 } from '@/features/account-profile/client' type Props = Readonly<{ error: Error & { digest?: string } - unstable_retry: () => void + retry: () => void }> -export default function CommonLayoutError({ error, unstable_retry }: Props) { +export default function CommonLayoutError({ error, retry }: Props) { const { t } = useTranslation('common') - const { reset } = useQueryErrorResetBoundary() + const { reset: resetQueries } = useQueryErrorResetBoundary() console.error(error) @@ -32,8 +32,8 @@ export default function CommonLayoutError({ error, unstable_retry }: Props) { size="small" variant="secondary" onClick={() => { - reset() - unstable_retry() + resetQueries() + retry() }} > {t(($) => $['errorBoundary.tryAgain'])} diff --git a/web/app/__tests__/error.spec.tsx b/web/app/__tests__/error.spec.tsx index c4695ca3f86..db99e79fc12 100644 --- a/web/app/__tests__/error.spec.tsx +++ b/web/app/__tests__/error.spec.tsx @@ -5,35 +5,48 @@ import { afterEach, describe, expect, it, vi } from 'vite-plus/test' import CommonLayoutError from '@/app/(commonLayout)/error' import AppError from '@/app/error' +type ErrorRecoveryProps = Readonly<{ + retry: () => void +}> + +const routeErrors = [ + { + name: 'root error', + renderError: (props: ErrorRecoveryProps) => , + }, + { + name: 'common layout error', + renderError: (props: ErrorRecoveryProps) => ( + + ), + }, +] + describe('route error recovery', () => { afterEach(() => { vi.restoreAllMocks() }) - it.each([ - { - name: 'root error', - renderError: (retry: () => void) => , + it.each(routeErrors)( + 'retries the $name after resetting query errors', + async ({ renderError }) => { + const user = userEvent.setup() + const retry = vi.fn() + vi.spyOn(console, 'error').mockImplementation(() => {}) + + render( + + {({ isReset }) => + renderError({ + retry: () => retry(isReset()), + }) + } + , + ) + + await user.click(screen.getByRole('button', { name: 'common.errorBoundary.tryAgain' })) + + expect(retry).toHaveBeenCalledWith(true) }, - { - name: 'common layout error', - renderError: (retry: () => void) => ( - - ), - }, - ])('resets failed queries before retrying the $name', async ({ renderError }) => { - const user = userEvent.setup() - const retry = vi.fn() - vi.spyOn(console, 'error').mockImplementation(() => {}) - - render( - - {({ isReset }) => renderError(() => retry(isReset()))} - , - ) - - await user.click(screen.getByRole('button', { name: 'common.errorBoundary.tryAgain' })) - - expect(retry).toHaveBeenCalledWith(true) - }) + ) }) diff --git a/web/app/error.tsx b/web/app/error.tsx index 52b9275a304..166ceee6f51 100644 --- a/web/app/error.tsx +++ b/web/app/error.tsx @@ -6,16 +6,14 @@ import { useTranslation } from 'react-i18next' import { FullScreenLoading } from '@/app/components/full-screen-loading' import { isLegacyBase401 } from '@/features/account-profile/client' -type Props = { +type Props = Readonly<{ error: Error & { digest?: string } - reset?: () => void - unstable_retry?: () => void -} + retry: () => void +}> -export default function AppError({ error, reset, unstable_retry }: Props) { +export default function AppError({ error, retry }: Props) { const { t } = useTranslation('common') const { reset: resetQueries } = useQueryErrorResetBoundary() - const retry = reset ?? unstable_retry console.error(error) @@ -26,18 +24,16 @@ export default function AppError({ error, reset, unstable_retry }: Props) {
{t(($) => $['errorBoundary.message'])}
- {retry && ( - - )} + ) }