"use client"; import { useEffect } from "react"; import { errorIdOf, recordErrorId, shortErrorId } from "@/lib/errors/error-id"; import { reloadOnceForChunkError } from "@/lib/pwa/chunk-reload"; /** * Root-level error boundary. Renders when even the root layout itself fails, * so it cannot rely on any providers (i18n, query, auth). Keep it static, * in English, and self-contained. */ export default function GlobalError({ error, reset, }: { error: Error & { digest?: string }; reset: () => void; }) { // A chunk of the root layout's client tree missing after a deploy lands // here rather than in `app/error.tsx`; it gets the same single reload. useEffect(() => { reloadOnceForChunkError(error); }, [error]); // The id the operator finds this failure by. No i18n provider exists at // this level, so the line is the same static bilingual pair as the heading. const errorId = errorIdOf(error, { unexpected: true }); useEffect(() => { if (errorId) recordErrorId(errorId); }, [errorId]); async function handleCopyId() { if (!errorId) return; try { await navigator.clipboard.writeText(errorId); } catch { window.prompt("Error ID", errorId); } } async function handleCopy() { // Strip query string — OAuth callback routes carry sensitive tokens. const loc = typeof window !== "undefined" ? window.location : null; const payload = { message: error.message, digest: error.digest, errorId, name: error.name, stack: error.stack?.split("\n").slice(0, 10).join("\n"), urlPath: loc?.pathname ?? null, userAgent: typeof navigator !== "undefined" ? navigator.userAgent : null, timestamp: new Date().toISOString(), }; const text = JSON.stringify(payload, null, 2); try { await navigator.clipboard.writeText(text); } catch { window.prompt("Copy details", text); } } return (
Ein kritischer Fehler ist aufgetreten. / A critical error occurred.
{error.message || "Unknown error"}
{errorId && (
Fehler-ID / Error ID
{shortErrorId(errorId)}