Files
cunkebao_v3/SuperAdmin/components/ErrorBoundary.tsx

100 lines
2.9 KiB
TypeScript
Raw Normal View History

2025-04-10 17:49:42 +08:00
"use client"
import React, { type ErrorInfo } from "react"
import { Card, CardContent, CardFooter } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { useRouter } from "next/navigation"
import { useToast } from "@/components/ui/use-toast"
interface ErrorBoundaryProps {
children: React.ReactNode
}
interface ErrorBoundaryState {
hasError: boolean
error?: Error
}
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props)
this.state = { hasError: false }
}
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
// 更新state使下一次渲染可以显示错误界面
return { hasError: true, error }
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// 记录错误信息
console.error("错误边界捕获到错误:", error, errorInfo)
}
render() {
if (this.state.hasError) {
return <ErrorScreen error={this.state.error} onReset={() => this.setState({ hasError: false })} />
}
return this.props.children
}
}
// 错误显示界面
function ErrorScreen({ error, onReset }: { error?: Error; onReset: () => void }) {
const router = useRouter()
const { toast } = useToast()
// 导航到主页
const goHome = () => {
router.push("/dashboard")
onReset()
}
// 刷新当前页面
const refreshPage = () => {
if (typeof window !== "undefined") {
toast({
title: "正在刷新页面",
description: "正在重新加载页面内容...",
variant: "default",
})
setTimeout(() => {
window.location.reload()
}, 500)
}
}
return (
<div className="w-full h-[calc(100vh-200px)] flex items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardContent className="pt-6">
<div className="flex flex-col gap-4">
<div className="bg-red-50 text-red-600 p-4 rounded-md">
<h2 className="text-xl font-semibold mb-2"></h2>
<p className="text-sm text-red-700 mb-4">
</p>
{error && (
<div className="bg-white/50 p-2 rounded text-xs font-mono overflow-auto max-h-24">
{error.message}
</div>
)}
</div>
<p className="text-sm text-gray-500">
</p>
</div>
</CardContent>
<CardFooter className="flex justify-end gap-2">
<Button variant="outline" onClick={goHome}>
</Button>
<Button onClick={refreshPage}></Button>
</CardFooter>
</Card>
</div>
)
}
export default ErrorBoundary