/** * Server-side error view for the cost center: **a single panel** — a row of small * stats up top (total / unexpected / expected / most common error code), * with a recent-errors table below (time, source · error code, kind, * message). What an error needs to answer is "what exactly went wrong" — a * detail table is more direct than a chart here: the count alone in the stats already covers the summary. * * Color semantics are consistent site-wide: unexpected (500s / runtime * exceptions) is a prominent rose; expected (HttpError, business 4xx) recedes into gray. * The outer frame is provided by the caller's ChartCard (full width, below the four business charts). */ import type { UsageErrors } from "@prismshadow/penguin-server/api"; import { S } from "../../lib/strings"; import { formatDateTime } from "../../lib/format"; import { Badge } from "../../components/ui/badge"; import { Empty } from "./usage-charts"; /** The two error categories. */ type ErrorKindKey = "unexpected" | "expected"; /** Copy: S is a runtime live binding (switching language remounts the whole tree), so it must be read at render time. */ function kindLabel(key: ErrorKindKey): string { return key === "unexpected" ? S.usage.errorsUnexpected : S.usage.errorsExpected; } function kindOf(kind: string): ErrorKindKey { return kind === "unexpected" ? "unexpected" : "expected"; } /** A single small stat: name + value, one row side by side (not turned into a chart). */ function Stat({ label, value, alert, muted, }: { label: string; value: string; /** Prominent value (unexpected errors): rose. */ alert?: boolean; muted?: boolean; }) { const tone = alert ? "text-rose-600 dark:text-rose-400" : muted ? "text-gray-500 dark:text-gray-400" : "text-gray-900 dark:text-gray-100"; return (
| {S.usage.errorsColTime} | {/* Wide enough to fully fit the longest error code: a tool failure's code carries the tool name (e.g. environment · tool_failed:exec_command), and truncating it would hide which tool failed. */}{S.usage.errorsColCode} | {S.usage.errorsColKind} | {S.usage.errorsColMessage} |
|---|---|---|---|
| {formatDateTime(e.ts)} | {e.source} · {e.code} |
|
{e.message} |