import { Link, useRouter } from "@tanstack/react-router";
import type { ErrorComponentProps } from "@tanstack/react-router";
import { ERROR_COPY, errorKind, type ErrorKind } from "~/lib/error-copy";
import { HttpError } from "~/server/errors";
import { Button, buttonClass } from "~/ui/Button";
import { ErrorScreen } from "~/ui/ErrorScreen";
const INTERNAL = 500;
const RETRYABLE: ReadonlySet<ErrorKind> = new Set(["server", "unavailable", "rate-limited"]);
/** HttpErrors carry user-facing messages; anything else may leak internals, so only show it in dev. */
function errorDetail(error: unknown): string | null {
if (error instanceof HttpError) return error.message;
if (import.meta.env.DEV && error instanceof Error) return error.message;
return null;
}
function PrimaryAction({ kind, onRetry }: { kind: ErrorKind; onRetry: () => void }) {
if (kind === "unauthorized") {
return (
<Link to="/login" className={buttonClass("primary")}>
Sign in
</Link>
);
}
if (!RETRYABLE.has(kind)) return null;
return (
<Button variant="primary" onClick={onRetry}>
Try again
</Button>
);
}
export function DefaultCatchBoundary({ error, reset }: ErrorComponentProps) {
const router = useRouter();
console.error("Route error:", error);
const status = error instanceof HttpError ? error.status : INTERNAL;
const kind = errorKind(status);
const copy = ERROR_COPY[kind];