fix(admin-web): 简化错误边界为静默 reload,去掉多余 UI

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-04 18:55:19 -08:00
parent f642ef1d56
commit 36b899d7ed
2 changed files with 11 additions and 161 deletions

View File

@ -2,91 +2,20 @@
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) {
const key = 'gcx_admin_reload_count';
const count = parseInt(sessionStorage.getItem(key) ?? '0', 10);
if (count < 3) {
sessionStorage.setItem(key, String(count + 1));
window.location.reload();
}
}, [error]);
return (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
minHeight: '400px',
fontFamily: 'system-ui, sans-serif',
}}
>
<div
style={{
textAlign: 'center',
padding: '40px',
background: '#fff',
borderRadius: '12px',
boxShadow: '0 2px 16px rgba(0,0,0,0.08)',
maxWidth: '400px',
}}
>
<div style={{ fontSize: '40px', marginBottom: '16px' }}></div>
<h2 style={{ margin: '0 0 8px', fontSize: '18px', color: '#1a1a1a' }}>
</h2>
<p style={{ margin: '0 0 24px', color: '#666', fontSize: '14px' }}>
</p>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'center' }}>
<button
onClick={() => window.location.reload()}
style={{
padding: '8px 20px',
background: '#2563eb',
color: '#fff',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
fontSize: '14px',
}}
>
</button>
<button
onClick={() => reset()}
style={{
padding: '8px 20px',
background: '#f5f5f5',
color: '#333',
border: '1px solid #e0e0e0',
borderRadius: '6px',
cursor: 'pointer',
fontSize: '14px',
}}
>
</button>
</div>
</div>
</div>
);
return null;
}

View File

@ -1,105 +1,26 @@
'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 <html><body> 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) {
// 捕获根级异常后立即刷新,防止无限循环限制 3 次
const key = 'gcx_admin_reload_count';
const count = parseInt(sessionStorage.getItem(key) ?? '0', 10);
if (count < 3) {
sessionStorage.setItem(key, String(count + 1));
window.location.reload();
}
}, [error]);
return (
<html lang="zh-CN">
<body
style={{
margin: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100vh',
background: '#f5f5f5',
fontFamily: 'system-ui, sans-serif',
}}
>
<div
style={{
textAlign: 'center',
padding: '40px',
background: '#fff',
borderRadius: '12px',
boxShadow: '0 2px 16px rgba(0,0,0,0.08)',
maxWidth: '400px',
}}
>
<div style={{ fontSize: '40px', marginBottom: '16px' }}></div>
<h2 style={{ margin: '0 0 8px', fontSize: '18px', color: '#1a1a1a' }}>
</h2>
<p style={{ margin: '0 0 24px', color: '#666', fontSize: '14px' }}>
</p>
<div style={{ display: 'flex', gap: '12px', justifyContent: 'center' }}>
<button
onClick={() => window.location.reload()}
style={{
padding: '8px 20px',
background: '#2563eb',
color: '#fff',
border: 'none',
borderRadius: '6px',
cursor: 'pointer',
fontSize: '14px',
}}
>
</button>
<button
onClick={() => reset()}
style={{
padding: '8px 20px',
background: '#f5f5f5',
color: '#333',
border: '1px solid #e0e0e0',
borderRadius: '6px',
cursor: 'pointer',
fontSize: '14px',
}}
>
</button>
</div>
</div>
</body>
<body />
</html>
);
}