"use client"; import { Component, type ErrorInfo, type ReactNode } from "react"; import { AlertCircle, RefreshCw } from "lucide-react"; import { Button } from "@/shared/components/ui/button"; import { cn } from "@/shared/lib/utils"; /** * SectionErrorBoundary - 区块级错误边界(用于 DashboardSection 内) * * 职责:隔离单个区块(如统计卡片组、图表区、列表区)的渲染错误, * 不影响其他区块和整个页面。 * * 与 RouteErrorBoundary 的区别: * - RouteErrorBoundary:整页崩溃兜底,由 Next.js error.tsx 触发 * - SectionErrorBoundary:区块崩溃隔离,由 DashboardSection 内部挂载 * * 与 PluginBoundary 的区别: * - PluginBoundary:单个插件崩溃隔离,含 Suspense + Skeleton * - SectionErrorBoundary:区块级(可能含多个插件),无 Suspense * * 关联:portal-shell README v2.0 §5.4 三级错误处理(L2 区块级) */ export interface SectionErrorBoundaryProps { children: ReactNode; /** 区块标题(用于错误 UI 显示,如 "统计概览") */ title?: string; /** 自定义错误降级 UI */ fallback?: (error: Error, reset: () => void) => ReactNode; /** 错误回调(上报) */ onError?: (error: Error, info: ErrorInfo) => void; /** 自定义类名 */ className?: string; } interface SectionErrorBoundaryState { error: Error | null; } export class SectionErrorBoundary extends Component< SectionErrorBoundaryProps, SectionErrorBoundaryState > { override state: SectionErrorBoundaryState = { error: null }; static getDerivedStateFromError(error: Error): SectionErrorBoundaryState { return { error }; } override componentDidCatch(error: Error, info: ErrorInfo): void { this.props.onError?.(error, info); } reset = (): void => { this.setState({ error: null }); }; override render(): ReactNode { const { error } = this.state; const { children, fallback, title, className } = this.props; if (error) { if (fallback) { return fallback(error, this.reset); } return (

{title ?? "区块加载失败"}

{error.message}

); } return children; } }