Skip to content

Instantly share code, notes, and snippets.

@NWYLZW
Created March 23, 2023 06:16
Show Gist options
  • Save NWYLZW/8d8d709eadf4e557bdabf2a52f39814d to your computer and use it in GitHub Desktop.
Save NWYLZW/8d8d709eadf4e557bdabf2a52f39814d to your computer and use it in GitHub Desktop.
Error Boundary???
import {
createContext, Dispatch,
PropsWithChildren, ReactElement, SetStateAction,
useCallback,
useContext, useEffect,
useMemo,
useState
} from 'react'
interface ErrorHandler {
e: Error
throwError: (error: string | Error) => ReactElement
ThrowError: (props: {
error: string | Error
}) => ReactElement
}
const ErrorHandler = createContext<ErrorHandler>(null)
function ErrorComp({ error, setE }: { error: Error, setE: Dispatch<SetStateAction<Error>> }) {
useEffect(() => {
setE(error)
}, [error, setE])
return <></>
}
export function useErrorHandler() {
const [e, setE] = useState<Error>()
const errorHandler = useMemo<ErrorHandler>(() => ({
e,
throwError(error) {
if (typeof error === 'string') {
error = new Error(error)
}
return <ErrorComp error={e} setE={setE}/>
},
ThrowError({ error }) {
return this.throwError(error)
},
}), [e])
return {
error: e,
ErrorHandler: useCallback(({ children }: PropsWithChildren) => <ErrorHandler.Provider value={errorHandler} >
{children}
</ErrorHandler.Provider>, [errorHandler])
}
}
export const useErrorHandlerContext = () => useContext(ErrorHandler)
export default function() {
const { error, ErrorHandler } = useErrorHandler()
return <ErrorHandler>
<More/>
<Label/>
<Control/>
</ErrorHandler>
}
function Control(props: { type: 'a' }) {
const errorHandler = useErrorHandlerContext()
if (props.type !== 'a')
return errorHandler.throwError(new Error('only support a type'))
return <>right</>
}
function More() {
const { e } = useErrorHandlerContext()
return <>
{e && <QuickFix />}
</>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment