/** * Dev-only error overlay. When a loader/action/render throws during `@nifrajs/web/vite` dev, this * renders a readable full-page overlay from a structured [Diagnostic] - the code, the message, a source * codeframe around the offending line, the recognised cause/fix when nifra has one, and the stack - * instead of a bare `err.stack` text dump. Dev-only by construction: it's called solely from the dev * server's catch, never in production (production maps errors to the `_error` route boundary). * * The overlay and the agent surfaces (`/__nifra/last-error`, `nifra_explain`) render from the SAME * `Diagnostic`, so a person and an agent see the identical failure, one as HTML and one as JSON. */ import type { Diagnostic } from "./diagnostic.ts" const esc = (s: string): string => s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """) /** The source codeframe block: numbered lines with the offending one highlighted. */ function codeframeHtml(diagnostic: Diagnostic): string { const cf = diagnostic.codeframe if (cf === undefined) return "" const loc = `${esc(cf.file)}:${cf.line}${cf.column !== undefined ? `:${cf.column}` : ""}` const rows = cf.lines .map( (l) => `
${esc(diagnostic.docsAnchor)}${esc(diagnostic.cause)}
` : "" return `${esc(diagnostic.fix)}
${anchor}No stack frames.
` return `