Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(react): prevent rendering fallback if not shouldCatch error
Browse files Browse the repository at this point in the history
Co-authored-by: lucas0530 <[email protected]>
Co-authored-by: HYUNGU KANG <[email protected]>
3 people committed Jan 10, 2025
1 parent 07b6b77 commit 5501676
Showing 6 changed files with 60 additions and 8 deletions.
5 changes: 5 additions & 0 deletions examples/visualization/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -31,6 +31,11 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<li>
<Link href="/react/ErrorBoundary/shouldCatch">{`<ErrorBoundary/>`} shouldCatch prop</Link>
</li>
<li>
<Link href="/react/ErrorBoundary/shouldCatch/renderPhase">
{`<ErrorBoundary/>`} shouldCatch prop render phase
</Link>
</li>
<li>
<Link href="/react/zodSearchParams">zod: no param</Link>
</li>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use client'

import { ErrorBoundary } from '@suspensive/react'
import { Throw } from '~/components/Throw'

export default function page() {
return (
<ErrorBoundary fallback={() => <>root fallback</>}>
<ErrorBoundary
shouldCatch={(error) => error.message !== 'children error message'}
fallback={() => {
console.log("child ErrorBoundary's fallback")
return <>child ErrorBoundary's fallback</>
}}
>
<Throw.Error message="children error message" after={2000}>
before throw Error
</Throw.Error>
</ErrorBoundary>
</ErrorBoundary>
)
}
13 changes: 13 additions & 0 deletions examples/visualization/src/components/Throw.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type PropsWithChildren, useState } from 'react'
import { useTimeout } from '~/hooks'

export const Throw = {
Error: ({ message, after = 0, children }: PropsWithChildren<{ message: string; after?: number }>) => {
const [isNeedThrow, setIsNeedThrow] = useState(after === 0)
if (isNeedThrow) {
throw new Error(message)
}
useTimeout(() => setIsNeedThrow(true), after)
return <>{children}</>
},
}
1 change: 1 addition & 0 deletions examples/visualization/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useTimeout } from './useTimeout'
11 changes: 11 additions & 0 deletions examples/visualization/src/hooks/useTimeout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { useCallback, useEffect, useRef } from 'react'

export const useTimeout = (fn: () => void, ms: number) => {
const fnRef = useRef(fn)
fnRef.current = fn
const fnPreserved = useCallback(() => fnRef.current(), [])
useEffect(() => {
const id = setTimeout(fnPreserved, ms)
return () => clearTimeout(id)
}, [fnPreserved, ms])
}
16 changes: 8 additions & 8 deletions packages/react/src/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -118,13 +118,6 @@ class BaseErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState
if (error instanceof SuspensiveError) {
throw error
}
const { shouldCatch = true } = this.props
const isCatch = Array.isArray(shouldCatch)
? shouldCatch.some((shouldCatch) => checkErrorBoundary(shouldCatch, error))
: checkErrorBoundary(shouldCatch, error)
if (!isCatch) {
throw error
}
this.props.onError?.(error, info)
}

@@ -134,12 +127,19 @@ class BaseErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState
}

render() {
const { children, fallback } = this.props
const { children, fallback, shouldCatch = true } = this.props
const { isError, error } = this.state

let childrenOrFallback = children

if (isError) {
const isCatch = Array.isArray(shouldCatch)
? shouldCatch.some((shouldCatch) => checkErrorBoundary(shouldCatch, error))
: checkErrorBoundary(shouldCatch, error)
if (!isCatch) {
throw error
}

if (typeof fallback === 'undefined') {
if (process.env.NODE_ENV === 'development') {
console.error('ErrorBoundary of @suspensive/react requires a defined fallback')

0 comments on commit 5501676

Please sign in to comment.