mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 08:48:10 +08:00
fix(web): use stable error boundary retry (#41811)
This commit is contained in:
parent
09f301d969
commit
b816754c06
@ -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'])}
|
||||
|
||||
@ -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) => <AppError error={new Error('failed')} {...props} />,
|
||||
},
|
||||
{
|
||||
name: 'common layout error',
|
||||
renderError: (props: ErrorRecoveryProps) => (
|
||||
<CommonLayoutError error={new Error('failed')} {...props} />
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
describe('route error recovery', () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{
|
||||
name: 'root error',
|
||||
renderError: (retry: () => void) => <AppError error={new Error('failed')} reset={retry} />,
|
||||
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(
|
||||
<QueryErrorResetBoundary>
|
||||
{({ isReset }) =>
|
||||
renderError({
|
||||
retry: () => retry(isReset()),
|
||||
})
|
||||
}
|
||||
</QueryErrorResetBoundary>,
|
||||
)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'common.errorBoundary.tryAgain' }))
|
||||
|
||||
expect(retry).toHaveBeenCalledWith(true)
|
||||
},
|
||||
{
|
||||
name: 'common layout error',
|
||||
renderError: (retry: () => void) => (
|
||||
<CommonLayoutError error={new Error('failed')} unstable_retry={retry} />
|
||||
),
|
||||
},
|
||||
])('resets failed queries before retrying the $name', async ({ renderError }) => {
|
||||
const user = userEvent.setup()
|
||||
const retry = vi.fn()
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
|
||||
render(
|
||||
<QueryErrorResetBoundary>
|
||||
{({ isReset }) => renderError(() => retry(isReset()))}
|
||||
</QueryErrorResetBoundary>,
|
||||
)
|
||||
|
||||
await user.click(screen.getByRole('button', { name: 'common.errorBoundary.tryAgain' }))
|
||||
|
||||
expect(retry).toHaveBeenCalledWith(true)
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
@ -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) {
|
||||
<div className="system-sm-regular text-text-tertiary">
|
||||
{t(($) => $['errorBoundary.message'])}
|
||||
</div>
|
||||
{retry && (
|
||||
<Button
|
||||
size="small"
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
resetQueries()
|
||||
retry()
|
||||
}}
|
||||
>
|
||||
{t(($) => $['errorBoundary.tryAgain'])}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
size="small"
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
resetQueries()
|
||||
retry()
|
||||
}}
|
||||
>
|
||||
{t(($) => $['errorBoundary.tryAgain'])}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user