Skip to content

Commit

Permalink
pretty error in preview, crash on build
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Mar 25, 2024
1 parent 47ede7f commit 7aa61cc
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/build.ts
Expand Up @@ -72,7 +72,7 @@ export async function build(
effects.output.write(`${faint("parse")} ${sourcePath} `);
const start = performance.now();
const source = await readFile(sourcePath, "utf8");
const page = parseMarkdown(source, options);
const page = parseMarkdown(source, {...options, build: true});
if (page.data.draft) {
effects.logger.log(faint("(skipped)"));
continue;
Expand Down
26 changes: 26 additions & 0 deletions src/frontMatter.ts
@@ -1,3 +1,4 @@
import matter from "gray-matter";
import {normalizeTheme} from "./config.js";

export interface FrontMatter {
Expand All @@ -12,6 +13,31 @@ export interface FrontMatter {
sql?: {[key: string]: string};
}

interface FrontMatterException {
reason: string;
mark: {buffer: string};
}

export function readFrontMatter(input: string, build: boolean): {content: string; data: FrontMatter} {
try {
const {content, data} = matter(input, {});
return {content, data: normalizeFrontMatter(data)};
} catch (error) {
if (!build && "mark" in (error as any)) {
const {
reason,
mark: {buffer}
} = error as FrontMatterException;
return {
content: `<div class="observablehq--inspect observablehq--error">Invalid front matter\n${reason}</div>
<pre>${String(buffer).slice(0, -1)}</pre>\n\n${input.slice(buffer.length + 6)}`,
data: {}
};
}
throw error;
}
}

export function normalizeFrontMatter(spec: any = {}): FrontMatter {
const frontMatter: FrontMatter = {};
if (spec == null || typeof spec !== "object") return frontMatter;
Expand Down
9 changes: 4 additions & 5 deletions src/markdown.ts
@@ -1,7 +1,6 @@
/* eslint-disable import/no-named-as-default-member */
import {createHash} from "node:crypto";
import {extname} from "node:path/posix";
import matter from "gray-matter";
import he from "he";
import MarkdownIt from "markdown-it";
import type {RuleCore} from "markdown-it/lib/parser_core.js";
Expand All @@ -11,7 +10,7 @@ import MarkdownItAnchor from "markdown-it-anchor";
import type {Config} from "./config.js";
import {mergeStyle} from "./config.js";
import type {FrontMatter} from "./frontMatter.js";
import {normalizeFrontMatter} from "./frontMatter.js";
import {readFrontMatter} from "./frontMatter.js";
import {rewriteHtmlPaths} from "./html.js";
import {parseInfo} from "./info.js";
import type {JavaScriptNode} from "./javascript/parse.js";
Expand Down Expand Up @@ -305,6 +304,7 @@ export interface ParseOptions {
head?: Config["head"];
header?: Config["header"];
footer?: Config["footer"];
build?: boolean;
}

export function createMarkdownIt({
Expand All @@ -327,9 +327,8 @@ export function createMarkdownIt({
}

export function parseMarkdown(input: string, options: ParseOptions): MarkdownPage {
const {md, path} = options;
const {content, data: frontMatter} = matter(input, {});
const data = normalizeFrontMatter(frontMatter);
const {md, path, build} = options;
const {content, data} = readFrontMatter(input, build);
const code: MarkdownCode[] = [];
const context: ParseContext = {code, startLine: 0, currentLine: 0, path};
const tokens = md.parse(content, context);
Expand Down

0 comments on commit 7aa61cc

Please sign in to comment.