Files
2026-10-08 11:09:37 +08:00

60 lines
1.7 KiB
TypeScript

"use client";
import { useEffect } from "react";
import { RotateCcw, TriangleAlert } from "lucide-react";
/**
* 错误边界(语言段内)。
*
* 必须是客户端组件。捕获渲染期间的运行时错误,
* 提供重试入口,并把错误上报到控制台便于排查。
*
* 注意:`error.message` 在生产环境会被脱敏,因此面向用户只展示通用文案,
* 详细信息(digest)留给开发者排查。
*/
export default function LocaleError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
console.error("[LocaleError]", error);
}, [error]);
return (
<section className="mx-auto flex min-h-[60vh] w-full max-w-[640px] flex-col items-center justify-center px-lg text-center">
<span
aria-hidden="true"
className="grid size-14 place-items-center rounded-full bg-brand-error/10"
>
<TriangleAlert className="size-6 text-brand-error" />
</span>
<h1 className="mt-lg text-heading-3 font-semibold text-ink">
出了点问题
</h1>
<p className="mt-sm max-w-[420px] text-body-md text-steel">
页面加载时发生了意外错误,请稍后重试。如果问题持续出现,请通过「关于」页的联系方式告诉我。
</p>
{error.digest ? (
<p className="mt-sm font-mono text-caption text-muted">
错误编号:{error.digest}
</p>
) : null}
<button
type="button"
onClick={reset}
className="mt-xxl inline-flex h-10 items-center gap-xs rounded-full bg-primary px-lg text-button-md font-medium text-on-primary transition-colors duration-150 active:bg-charcoal"
>
<RotateCcw className="size-4" aria-hidden="true" />
重试
</button>
</section>
);
}