import { useMemo } from "react"; import { getRecentErrors } from "../api"; import { formatCost, formatInteger, formatRelativeTime } from "../data/formatters"; import { useResource } from "../data/useResource"; import type { MessageStats, TimeRange } from "../types"; import { AsyncBoundary, DataTable, Panel, StatusPill } from "../ui"; export interface ErrorsRouteProps { active: boolean; range: TimeRange; refreshTrigger: number; onRequestClick: (id: number) => void; } export function ErrorsRoute({ active, refreshTrigger, onRequestClick }: ErrorsRouteProps) { const { data: recentErrors, error, loading, } = useResource(["recent-errors-dense", refreshTrigger], signal => getRecentErrors(50, signal), { pollMs: 30000, enabled: active, }); const columns = useMemo( () => [ { key: "model", header: "Model", render: (item: MessageStats) => (
{item.model}
{item.provider}
), }, { key: "timestamp", header: "Time", render: (item: MessageStats) => formatRelativeTime(item.timestamp), }, { key: "errorMessage", header: "Error Message", render: (item: MessageStats) => (
{item.errorMessage || "Unknown error"}
), }, { key: "tokens", header: "Tokens", numeric: true, render: (item: MessageStats) => formatInteger(item.usage.totalTokens), }, { key: "cost", header: "Cost", numeric: true, render: (item: MessageStats) => formatCost(item.usage.cost.total, 4), }, ], [], ); const renderMobileCard = (item: MessageStats, onClick?: () => void) => (
{item.model}
{item.provider}
Failed
Time
{formatRelativeTime(item.timestamp)}
Cost
{formatCost(item.usage.cost.total, 4)}
Tokens
{formatInteger(item.usage.totalTokens)}
{item.errorMessage &&
{item.errorMessage}
}
); return (
item.id || `${item.sessionFile}-${item.entryId}`} onRowClick={item => item.id && onRequestClick(item.id)} renderMobileCard={renderMobileCard} emptyText="No recent failures in the local stats database" />
); }