示例说明
SSR 期间的数据或渲染异常会把整个请求打崩,错误边界把爆炸半径缩到路由段内:页面其余部分照常渲染。Next 的约定文件 error.tsx 自动成为该层边界;error 对象的 digest 是服务端生成的指纹,用它能在服务端日志里精确定位这一场失败——前后端日志靠这个键缝合。
技术要点
- error.tsx 约定文件自动充当边界
- digest 连接客户端错误与服务端日志
- reset 只重渲染出错区段
代码解读
组件按错误内容分流:鉴权类失败渲染引导登录的静态内容;其余可重试错误展示说明与重试按钮,reset 触发该区段重新服务端渲染。useEffect 里的日志记录带 digest,排障时在服务端按指纹检索完整堆栈。
使用建议
不要在边界里吞掉所有错误,未知失败要上报监控。根级 not-found 与 error 分工明确。可重试判定逻辑保持简单,复杂分类放服务端。
代码示例
// serverSide rendering error boundary recovery
// app/dashboard/error.tsx — 路由级错误边界(客户端组件)
'use client';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
interface DashboardErrorProps {
error: Error & { digest?: string };
reset: () => void;
}
export default function DashboardError({ error, reset }: DashboardErrorProps) {
const router = useRouter();
const isRetryable = !error.message.includes('authorization');
useEffect(() => {
// digest 由服务端生成,用于在日志中精确定位本次渲染失败
console.error('dashboard render failed:', error.digest, error.message);
}, [error]);
if (!isRetryable) {
return (
<section role="alert">
<h2>Access denied</h2>
<button onClick={() => router.push('/login')}>Go to login</button>
</section>
);
}
return (
<section role="alert">
<h2>Dashboard failed to render</h2>
<p>This section hit a transient error. Other page areas still work.</p>
<button onClick={() => reset()}>Retry this section</button>
</section>
);
}
// 服务端组件抛错示例:
// export default async function Page() {
// const stats = await fetchStats(); // 抛错时仅该段被边界捕获
// return <StatsCard stats={stats} />;
// }