CLI prints a raw stack trace instead of an error message #102

Closed
opened 2026-09-23 05:34:58 +02:00 by clawbot · 1 comment
Collaborator

Problem

Any error a command throws reaches the user as a raw Node stack trace. The commands leave thrown errors to their caller (src/cli-commands.ts:3-4). run in bin/quak.ts:49-62 does not catch them, and program.parse() (bin/quak.ts:172) does not await async actions, so the rejection is unhandled. Reproduced on next2:

$ quak --cache-dir /dev/null/x collections
node:internal/fs/promises:1605
  return await PromisePrototypeThen(
Error: ENOTDIR: not a directory, mkdir '/dev/null/x/originals'
    at async mkdir (node:internal/fs/promises:1605:10)
    ... 12 more lines ...
Node.js v26.7.0

The same happens for everyday failures: no network, an expired session in collections, files, get or get-thumb, or a disk-full error during get.

Definition of done

  1. bin/quak.ts uses program.parseAsync(). The wrapper catches any error from a command, prints quak: MESSAGE on one line to stderr, and exits 1 once output has drained.
  2. The wrapper lives in src/ so it can be tested. A test shows that a command which throws produces that one line and exit code 1, and no stack trace.
  3. make check green; TODO.md updated in the same commit.

Model: opus-5-5

## Problem Any error a command throws reaches the user as a raw Node stack trace. The commands leave thrown errors to their caller (`src/cli-commands.ts:3-4`). `run` in `bin/quak.ts:49-62` does not catch them, and `program.parse()` (`bin/quak.ts:172`) does not await async actions, so the rejection is unhandled. Reproduced on `next2`: ``` $ quak --cache-dir /dev/null/x collections node:internal/fs/promises:1605 return await PromisePrototypeThen( Error: ENOTDIR: not a directory, mkdir '/dev/null/x/originals' at async mkdir (node:internal/fs/promises:1605:10) ... 12 more lines ... Node.js v26.7.0 ``` The same happens for everyday failures: no network, an expired session in `collections`, `files`, `get` or `get-thumb`, or a disk-full error during `get`. ## Definition of done 1. `bin/quak.ts` uses `program.parseAsync()`. The wrapper catches any error from a command, prints `quak: MESSAGE` on one line to stderr, and exits 1 once output has drained. 2. The wrapper lives in `src/` so it can be tested. A test shows that a command which throws produces that one line and exit code 1, and no stack trace. 3. `make check` green; `TODO.md` updated in the same commit. Model: opus-5-5
clawbot self-assigned this 2026-09-23 05:34:58 +02:00
Author
Collaborator

Implemented in #121: a thrown command error now prints one quak: MESSAGE line on stderr and exits 1; the wrapper lives in src/cli-run.ts with a test, and bin/quak.ts awaits program.parseAsync().

Model: opus-5-5

Implemented in https://git.eeqj.de/sneak/quak/pulls/121: a thrown command error now prints one `quak: MESSAGE` line on stderr and exits 1; the wrapper lives in `src/cli-run.ts` with a test, and `bin/quak.ts` awaits `program.parseAsync()`. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/quak#102