From 91813b4165fb6388603a5594fca98a20e262d07b Mon Sep 17 00:00:00 2001 From: Endeavorance Date: Tue, 25 Feb 2025 16:12:53 -0500 Subject: [PATCH] Improved error reporting --- bun.lock | 4 ++-- package.json | 2 +- src/errors.ts | 20 ++++++++++++++++++++ src/index.ts | 9 ++++----- src/resource.ts | 30 +++++++++++++++++++++--------- 5 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 src/errors.ts diff --git a/bun.lock b/bun.lock index 5e4cf48..25441af 100644 --- a/bun.lock +++ b/bun.lock @@ -4,7 +4,7 @@ "": { "name": "@proscenium/muse", "dependencies": { - "@proscenium/playbill": "0.0.2", + "@proscenium/playbill": "0.0.3", "chalk": "^5.4.1", "yaml": "^2.7.0", "zod": "^3.24.1", @@ -37,7 +37,7 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], - "@proscenium/playbill": ["@proscenium/playbill@0.0.2", "https://git.astral.camp/api/packages/proscenium/npm/%40proscenium%2Fplaybill/-/0.0.2/playbill-0.0.2.tgz", { "peerDependencies": { "typescript": "^5" } }, "sha512-eXrfAK9xQzr0AnY3QJcY+DujWafJh6ntO5KYDdhWE4HE5VfWrLVk42LVFlM7HDkulnjwa6uvwaET2QrR3RWKlw=="], + "@proscenium/playbill": ["@proscenium/playbill@0.0.3", "https://git.astral.camp/api/packages/proscenium/npm/%40proscenium%2Fplaybill/-/0.0.3/playbill-0.0.3.tgz", { "peerDependencies": { "typescript": "^5" } }, "sha512-cHG1BLghkVfrABZdBNKZEPctBJyJMTQq5lTW3IU44JSYJurJATGOEsFLqBgLPoKpJGKmVFtXREinG6hYrX9a0g=="], "@types/bun": ["@types/bun@1.2.3", "", { "dependencies": { "bun-types": "1.2.3" } }, "sha512-054h79ipETRfjtsCW9qJK8Ipof67Pw9bodFWmkfkaUaRiIQ1dIV2VTlheshlBx3mpKr0KeK8VqnMMCtgN9rQtw=="], diff --git a/package.json b/package.json index 957d4b9..bccca50 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "chalk": "^5.4.1", "yaml": "^2.7.0", "zod": "^3.24.1", - "@proscenium/playbill": "0.0.2" + "@proscenium/playbill": "0.0.3" }, "scripts": { "fmt": "bunx --bun biome check --fix", diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..eb5bcbb --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,20 @@ +export class MuseError extends Error { + fmt(): string { + return this.message; + } +} + +export class ResourceFileError extends MuseError { + filePath: string; + details?: string; + + constructor(message: string, filePath: string, details?: string) { + super(message); + this.filePath = filePath; + this.details = details; + } + + fmt(): string { + return `-- ${this.message} --\nFile Path: ${this.filePath}\nDetails: ${this.details}`; + } +} diff --git a/src/index.ts b/src/index.ts index 3a9f14e..0ec2a2a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,6 +9,7 @@ import chalk from "chalk"; import { parseBindingFile } from "./binding"; import { loadResourceFile } from "./resource"; import { usage } from "./usage"; +import { ResourceFileError } from "./errors"; enum ExitCode { Success = 0, @@ -201,12 +202,10 @@ try { const exitCode = await main(); process.exit(exitCode); } catch (error) { - if (error instanceof Error) { - console.error("Uncaught error:"); - console.error(chalk.red(error.message)); - console.error(error.stack); + if (error instanceof ResourceFileError) { + console.error(chalk.red(error.fmt())); } else { - console.error("An unknown error occurred"); + console.error("An unexpected error occurred"); console.error(error); } diff --git a/src/resource.ts b/src/resource.ts index 0063ec9..228e7b9 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -4,11 +4,11 @@ import { ResourceMap, } from "@proscenium/playbill"; import YAML, { YAMLParseError } from "yaml"; +import { ZodError } from "zod"; +import { ResourceFileError } from "./errors"; import { extractFrontmatter, extractMarkdown } from "./markdown"; type FileFormat = "yaml" | "markdown"; -export class ResourceFileError extends Error { } -export class NullResourceError extends Error { } function determineFileFormat(filePath: string): FileFormat { return filePath.split(".").pop() === "md" ? "markdown" : "yaml"; @@ -18,22 +18,22 @@ function loadYamlResourceFile(filePath: string, text: string): AnyResource[] { const parsedDocs = YAML.parseAllDocuments(text); if (parsedDocs.some((doc) => doc.toJS() === null)) { - throw new NullResourceError(`Null resource defined in ${filePath}`); + throw new ResourceFileError("Encountered NULL resource", filePath); } const errors = parsedDocs.flatMap((doc) => doc.errors); if (errors.length > 0) { - throw new ResourceFileError(`Error parsing ${filePath}: ${errors}`); + throw new ResourceFileError( + "Error parsing YAML resource", + filePath, + errors.map((e) => e.message).join(", "), + ); } const collection: AnyResource[] = []; for (const doc of parsedDocs) { - if (doc.errors.length > 0) { - throw new ResourceFileError(`Error parsing ${filePath}: ${doc.errors}`); - } - const raw = doc.toJS(); const parsed = AnyResourceSchema.parse(raw); const type = parsed.$define; @@ -62,7 +62,19 @@ function loadMarkdownResourceFile( return [parsed]; } catch (e) { if (e instanceof YAMLParseError) { - throw new ResourceFileError(`Error parsing frontmatter in ${filePath}`); + throw new ResourceFileError( + "Error parsing Markdown frontmatter", + filePath, + e.message, + ); + } + + if (e instanceof ZodError) { + throw new ResourceFileError( + "Error parsing resource file", + filePath, + e.message, + ); } throw e;