diff --git a/frontend/admin-web/src/app/(admin)/error.tsx b/frontend/admin-web/src/app/(admin)/error.tsx new file mode 100644 index 0000000..008a73c --- /dev/null +++ b/frontend/admin-web/src/app/(admin)/error.tsx @@ -0,0 +1,92 @@ +'use client'; + +import { useEffect } from 'react'; + +/** + * Admin 路由段错误边界 + * + * 捕获 (admin) 路由内的客户端异常。 + * 当检测到 Next.js stale bundle / Server Action 不匹配错误时自动刷新页面。 + */ +export default function AdminError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + useEffect(() => { + const msg = error?.message ?? ''; + const isStaleBundle = + msg.includes('Server Action') || + msg.includes('Failed to find') || + msg.includes('An unexpected response was received') || + (error?.digest ?? '').startsWith('NEXT_'); + + if (isStaleBundle) { + window.location.reload(); + } + }, [error]); + + return ( +
+
+
⚠️
+

+ 页面加载出错 +

+

+ 检测到新版本,正在自动刷新… +

+
+ + +
+
+
+ ); +} diff --git a/frontend/admin-web/src/app/global-error.tsx b/frontend/admin-web/src/app/global-error.tsx new file mode 100644 index 0000000..05e84ce --- /dev/null +++ b/frontend/admin-web/src/app/global-error.tsx @@ -0,0 +1,105 @@ +'use client'; + +/** + * Next.js App Router 根级错误边界 + * + * 捕获未处理的客户端异常,避免显示 Next.js 默认的 + * "Application error: a client-side exception has occurred" 全屏崩溃页。 + * + * 常见触发场景: + * - 重新部署后,浏览器仍持有旧 bundle,内部 Server Action ID("r" / "multi") + * 已不匹配新服务器构建 → Failed to find Server Action → 客户端异常 + * - 此时自动刷新页面即可恢复正常(加载新 bundle) + * + * global-error.tsx 必须自带 ,因为它会替换根 layout。 + */ + +import { useEffect } from 'react'; + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + useEffect(() => { + // 检测 Next.js stale bundle 导致的 Server Action 不匹配错误 + // 自动刷新页面以加载新版本 + const msg = error?.message ?? ''; + const isStaleBundle = + msg.includes('Server Action') || + msg.includes('Failed to find') || + msg.includes('An unexpected response was received') || + (error?.digest ?? '').startsWith('NEXT_'); + + if (isStaleBundle) { + window.location.reload(); + } + }, [error]); + + return ( + + +
+
⚠️
+

+ 页面加载出错 +

+

+ 检测到新版本,正在自动刷新… +

+
+ + +
+
+ + + ); +}