66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
"use client";
|
||
|
||
/**
|
||
* 全局 Error Boundary
|
||
*
|
||
* Next.js 16 文档要求 global-error 必须是 Client Component。
|
||
* 16.2.7 存在 prerender `/_global-error` 的内部 bug(workStore 未初始化),
|
||
* 本文件通过不挂任何 Client Context 副作用、纯静态 HTML 输出来规避。
|
||
*
|
||
* 当根 layout 自身抛出错误时渲染;必须包含 `<html>` + `<body>`,
|
||
* 因为它会替换根 layout。
|
||
*/
|
||
|
||
import { ExceptionHandler } from "@/core/errors";
|
||
|
||
interface GlobalErrorProps {
|
||
error: Error & { digest?: string };
|
||
unstable_retry?: () => void;
|
||
}
|
||
|
||
export default function GlobalError({ error }: GlobalErrorProps) {
|
||
const errorMessage = ExceptionHandler.message(
|
||
error,
|
||
"An unexpected error occurred.",
|
||
);
|
||
|
||
return (
|
||
<html lang="en">
|
||
<body
|
||
style={{
|
||
fontFamily: "system-ui, sans-serif",
|
||
padding: "2rem",
|
||
background: "#111",
|
||
color: "#fff",
|
||
minHeight: "100vh",
|
||
}}
|
||
>
|
||
<h1 style={{ fontSize: "1.5rem", marginBottom: "1rem" }}>
|
||
Something went wrong
|
||
</h1>
|
||
<p style={{ marginBottom: "1rem", opacity: 0.8 }}>
|
||
{errorMessage}
|
||
</p>
|
||
<button
|
||
type="button"
|
||
onClick={() => {
|
||
window.location.href = "/";
|
||
}}
|
||
style={{
|
||
display: "inline-block",
|
||
padding: "0.5rem 1rem",
|
||
background: "#4f46e5",
|
||
color: "#fff",
|
||
borderRadius: "0.5rem",
|
||
border: 0,
|
||
cursor: "pointer",
|
||
fontSize: "1rem",
|
||
}}
|
||
>
|
||
Back to start
|
||
</button>
|
||
</body>
|
||
</html>
|
||
);
|
||
}
|