UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

134 lines (133 loc) 4.31 kB
import * as fs from "node:fs"; import { fileURLToPath } from "node:url"; import { codeToHtml, createCssVariablesTheme } from "shiki"; import { FailedToLoadModuleSSR, InvalidGlob, MdxIntegrationMissingError } from "../errors-data.js"; import { AstroError } from "../errors.js"; import { createSafeError } from "../utils.js"; import { getDocsForError, renderErrorMarkdown } from "./utils.js"; function enhanceViteSSRError({ error, filePath, loader, renderers }) { let safeError = createSafeError(error); if (loader) { try { loader.fixStacktrace(safeError); } catch { } } if (filePath) { const path = fileURLToPath(filePath); const content = fs.readFileSync(path).toString(); const lns = content.split("\n"); let importName; if (importName = /Failed to load url (.*?) \(resolved id:/.exec(safeError.message)?.[1]) { safeError.title = FailedToLoadModuleSSR.title; safeError.name = "FailedToLoadModuleSSR"; safeError.message = FailedToLoadModuleSSR.message(importName); safeError.hint = FailedToLoadModuleSSR.hint; const line = lns.findIndex((ln) => ln.includes(importName)); if (line !== -1) { const column = lns[line]?.indexOf(importName); safeError.loc = { file: path, line: line + 1, column }; } } const fileId = safeError.id ?? safeError.loc?.file; if (fileId && !renderers?.find((r) => r.name === "@astrojs/mdx") && safeError.message.includes("Syntax error") && /.mdx$/.test(fileId)) { safeError = new AstroError({ ...MdxIntegrationMissingError, message: MdxIntegrationMissingError.message(JSON.stringify(fileId)), location: safeError.loc, stack: safeError.stack }); } if (safeError.message.includes("Invalid glob")) { const globPattern = /glob: "(.+)" \(/.exec(safeError.message)?.[1]; if (globPattern) { safeError.message = InvalidGlob.message(globPattern); safeError.name = "InvalidGlob"; safeError.title = InvalidGlob.title; const line = lns.findIndex((ln) => ln.includes(globPattern)); if (line !== -1) { const column = lns[line]?.indexOf(globPattern); safeError.loc = { file: path, line: line + 1, column }; } } } } return safeError; } const ALTERNATIVE_JS_EXTS = ["cjs", "mjs"]; const ALTERNATIVE_MD_EXTS = ["mdoc"]; let _cssVariablesTheme; const cssVariablesTheme = () => _cssVariablesTheme ?? (_cssVariablesTheme = createCssVariablesTheme({ variablePrefix: "--astro-code-" })); async function getViteErrorPayload(err) { let plugin = err.plugin; if (!plugin && err.hint) { plugin = "astro"; } const message = renderErrorMarkdown(err.message.trim(), "html"); const hint = err.hint ? renderErrorMarkdown(err.hint.trim(), "html") : void 0; const docslink = getDocsForError(err); let highlighterLang = err.loc?.file?.split(".").pop(); if (ALTERNATIVE_JS_EXTS.includes(highlighterLang ?? "")) { highlighterLang = "js"; } else if (ALTERNATIVE_MD_EXTS.includes(highlighterLang ?? "")) { highlighterLang = "md"; } const highlightedCode = err.fullCode ? await codeToHtml(err.fullCode, { lang: highlighterLang ?? "text", theme: cssVariablesTheme(), transformers: [ transformerCompactLineOptions( err.loc?.line ? [{ line: err.loc.line, classes: ["error-line"] }] : void 0 ) ] }) : void 0; return { __isEnhancedAstroErrorPayload: true, type: "error", err: { ...err, name: err.name, type: err.type, message, hint, frame: err.frame, highlightedCode, docslink, loc: { file: err.loc?.file, line: err.loc?.line, column: err.loc?.column }, plugin, stack: err.stack, cause: err.cause } }; } function transformerCompactLineOptions(lineOptions = []) { return { name: "@shikijs/transformers:compact-line-options", line(node, line) { const lineOption = lineOptions.find((o) => o.line === line); if (lineOption?.classes) this.addClassToHast(node, lineOption.classes); return node; } }; } export { enhanceViteSSRError, getViteErrorPayload };