Files
SnowLuma/.pnpm-store/v11/files/29/d675e5f17f9e1941b019d9b0341984bd9036ba64bbecb2321f3424a55b6a081df728fdc795042d31076f38dab355c32cf02e46dbfa9b3e8f6e9759770a3436
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Canceled after 0s
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

117 lines
2.9 KiB
Plaintext

'use client'
import * as React from 'react'
import type { ErrorRouteComponent } from './route'
import type { ErrorInfo } from 'react'
export function CatchBoundary(props: {
getResetKey: () => number | string
children: React.ReactNode
errorComponent?: ErrorRouteComponent
onCatch?: (error: Error, errorInfo: ErrorInfo) => void
}) {
const errorComponent = props.errorComponent ?? ErrorComponent
return (
<CatchBoundaryImpl
getResetKey={props.getResetKey}
onCatch={props.onCatch}
children={({ error, reset }) => {
if (error) {
return React.createElement(errorComponent, {
error,
reset,
})
}
return props.children
}}
/>
)
}
class CatchBoundaryImpl extends React.Component<{
getResetKey: () => number | string
children: (props: {
error: Error | null
reset: () => void
}) => React.ReactNode
onCatch?: (error: Error, errorInfo: ErrorInfo) => void
}> {
state = { error: null } as { error: Error | null; resetKey?: string | number }
static getDerivedStateFromProps(
props: { getResetKey: () => string | number },
state: { resetKey?: string | number; error: Error | null },
) {
const resetKey = props.getResetKey()
if (state.error && state.resetKey !== resetKey) {
return { resetKey, error: null }
}
return { resetKey }
}
static getDerivedStateFromError(error: Error) {
return { error }
}
reset() {
this.setState({ error: null })
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
if (this.props.onCatch) {
this.props.onCatch(error, errorInfo)
}
}
render() {
return this.props.children({
error: this.state.error,
reset: () => {
this.reset()
},
})
}
}
export function ErrorComponent({ error }: { error: any }) {
const [show, setShow] = React.useState(process.env.NODE_ENV !== 'production')
return (
<div style={{ padding: '.5rem', maxWidth: '100%' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '.5rem' }}>
<strong style={{ fontSize: '1rem' }}>Something went wrong!</strong>
<button
style={{
appearance: 'none',
fontSize: '.6em',
border: '1px solid currentColor',
padding: '.1rem .2rem',
fontWeight: 'bold',
borderRadius: '.25rem',
}}
onClick={() => setShow((d) => !d)}
>
{show ? 'Hide Error' : 'Show Error'}
</button>
</div>
<div style={{ height: '.25rem' }} />
{show ? (
<div>
<pre
style={{
fontSize: '.7em',
border: '1px solid red',
borderRadius: '.25rem',
padding: '.3rem',
color: 'red',
overflow: 'auto',
}}
>
{error.message ? <code>{error.message}</code> : null}
</pre>
</div>
) : null}
</div>
)
}