Improved error reporting

This commit is contained in:
Endeavorance 2025-02-25 16:12:53 -05:00
parent d4eb0c8a4f
commit 91813b4165
5 changed files with 48 additions and 17 deletions

20
src/errors.ts Normal file
View file

@ -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}`;
}
}

View file

@ -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);
}

View file

@ -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;