From bf8b1d16f815f0ee8dc584d78a5402aa94cf77b0 Mon Sep 17 00:00:00 2001 From: "Ricardo Q. Bazan" Date: Fri, 13 Mar 2026 22:07:47 -0500 Subject: [PATCH 1/2] fix(clibuddy): add `run` helper with better error messaging Extract shared CLI entry point logic into a `run` function in clibuddy. Handles non-Error throwables like Bun's ResolveMessage which have a `.message` property but don't extend Error, preventing opaque output like "ResolveMessage {}". Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/clibuddy/src/index.ts | 1 + packages/clibuddy/src/run.ts | 26 ++++++++++++++++++++++++++ packages/run-run/src/main.ts | 11 +++-------- packages/starter/src/main.ts | 8 +++----- 4 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 packages/clibuddy/src/run.ts diff --git a/packages/clibuddy/src/index.ts b/packages/clibuddy/src/index.ts index e7fcd10..997a31c 100644 --- a/packages/clibuddy/src/index.ts +++ b/packages/clibuddy/src/index.ts @@ -1,3 +1,4 @@ export * from "./colors"; +export * from "./run"; export * from "./services"; export * from "./version"; diff --git a/packages/clibuddy/src/run.ts b/packages/clibuddy/src/run.ts new file mode 100644 index 0000000..724cb35 --- /dev/null +++ b/packages/clibuddy/src/run.ts @@ -0,0 +1,26 @@ +import { isProcessOutput } from "./services/shell/utils"; + +function hasMessage(error: unknown): error is { message: string } { + return ( + typeof error === "object" && + error !== null && + "message" in error && + typeof (error as { message: unknown }).message === "string" + ); +} + +function formatError(error: unknown): string { + if (hasMessage(error)) return error.message; + return String(error); +} + +export async function run(fn: () => Promise, logger: { error: (...args: unknown[]) => void }) { + try { + await fn(); + } catch (error) { + if (!isProcessOutput(error)) { + logger.error(formatError(error)); + } + process.exit(1); + } +} diff --git a/packages/run-run/src/main.ts b/packages/run-run/src/main.ts index 5c2a65e..de8bf37 100644 --- a/packages/run-run/src/main.ts +++ b/packages/run-run/src/main.ts @@ -1,16 +1,11 @@ -import { isProcessOutput } from "@vlandoss/clibuddy"; +import { run } from "@vlandoss/clibuddy"; import { createProgram, type Options } from "./program"; import { parseArgs } from "./program/parse-args"; import { logger } from "./services/logger"; export async function main(options: Options) { - try { + await run(async () => { const { program } = await createProgram(options); await program.parseAsync(parseArgs(), { from: "user" }); - } catch (error) { - if (!isProcessOutput(error)) { - logger.error("Cannot run main successfully", error); - } - process.exit(1); - } + }, logger); } diff --git a/packages/starter/src/main.ts b/packages/starter/src/main.ts index f2a9450..4fb32a1 100644 --- a/packages/starter/src/main.ts +++ b/packages/starter/src/main.ts @@ -1,12 +1,10 @@ +import { run } from "@vlandoss/clibuddy"; import { createProgram, type Options } from "./program"; import { logger } from "./services/logger"; export async function main(options: Options) { - try { + await run(async () => { const program = await createProgram(options); await program.parseAsync(); - } catch (error) { - logger.error("Cannot run main successfully", error); - process.exit(1); - } + }, logger); } From b6db97f82a0f2670ab8d4f9e3b33afef8b0671cd Mon Sep 17 00:00:00 2001 From: "Ricardo Q. Bazan" Date: Fri, 13 Mar 2026 22:09:28 -0500 Subject: [PATCH 2/2] docs(changeset): Improve fatal error logging --- .changeset/curly-worlds-sing.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/curly-worlds-sing.md diff --git a/.changeset/curly-worlds-sing.md b/.changeset/curly-worlds-sing.md new file mode 100644 index 0000000..4ab1646 --- /dev/null +++ b/.changeset/curly-worlds-sing.md @@ -0,0 +1,7 @@ +--- +"@vlandoss/clibuddy": patch +"@vlandoss/run-run": patch +"@vlandoss/starter": patch +--- + +Improve fatal error logging