# errors _(no submodules)_ ## Purpose The `errors` module defines the complete error taxonomy for `@suaveplan/cli`. It provides a stable, machine-readable code registry (`CLI_CODES`) and a strongly-typed error class (`CliError`) so that every failure surface in the CLI framework is discriminable at runtime without string-matching on messages. Callers can switch exhaustively on `err.code`, log structured records with stable identifiers, and forward typed errors across process boundaries without losing fidelity. ## Features - **Three sub-namespaces** — `CLI.PARSE.*` covers argument/option parsing failures; `CLI.COMMAND.*` covers command-dispatch failures; `CLI.APP.*` covers top-level application lifecycle failures. - **Nine stable error codes** — each code is a dot-delimited string constant produced by `defineCodes()` from `@suaveplan/error`, guaranteeing uniqueness and structural consistency across the codebase. - **`CliCode` union type** — narrows the full set of valid codes for use in generic `SuaveplanError` type parameters and exhaustive switch statements. - **`CliError` class** — extends `SuaveplanError` with a public constructor, cause chaining, and structured `context` attachment for diagnostic metadata. - **Zero runtime overhead** — the `CLI_CODES` object is `as const`, so all string values are inlined at the call site by the TypeScript compiler. ## Usage: Basic Example ```ts import { CliError, CLI_CODES } from "@suaveplan/cli/errors/errors"; function assertKnownOption(flag: string, known: Set): void { if (!known.has(flag)) { throw new CliError( CLI_CODES.PARSE.UNKNOWN_OPTION, "cli.parse.unknown_option" ); } } ``` ## Usage: Advanced Example ```ts import { CliError, CLI_CODES } from "@suaveplan/cli/errors/errors"; import { SuaveplanError } from "@suaveplan/error"; async function runApp(signal: AbortSignal): Promise { try { await doWork(signal); } catch (err) { if (signal.aborted) { throw new CliError(CLI_CODES.APP.ABORTED, "cli.app.aborted", { cause: err instanceof Error ? err : undefined, context: { reason: signal.reason }, }); } throw new CliError(CLI_CODES.APP.RUN_FAILED, "cli.app.run_failed", { cause: err instanceof Error ? err : undefined, }); } } function handleError(err: unknown): void { if (err instanceof CliError) { // Narrow on the stable code — no message-string matching needed. switch (err.code) { case CLI_CODES.APP.ABORTED: process.exitCode = 130; // standard SIGINT exit code break; case CLI_CODES.PARSE.UNKNOWN_OPTION: console.error(`Unknown option: ${String(err.context?.["option"])}`); process.exitCode = 1; break; default: console.error(err.message); process.exitCode = 1; } } } ``` ## API Reference ### `CLI_CODES` ```ts const CLI_CODES: { PARSE: { UNKNOWN_OPTION: "CLI.PARSE.UNKNOWN_OPTION"; MISSING_VALUE: "CLI.PARSE.MISSING_VALUE"; INVALID_VALUE: "CLI.PARSE.INVALID_VALUE"; MISSING_ARGUMENT: "CLI.PARSE.MISSING_ARGUMENT"; MISSING_REQUIRED_OPTION: "CLI.PARSE.MISSING_REQUIRED_OPTION"; }; COMMAND: { NO_ACTION: "CLI.COMMAND.NO_ACTION"; UNKNOWN_SUBCOMMAND: "CLI.COMMAND.UNKNOWN_SUBCOMMAND"; }; APP: { RUN_FAILED: "CLI.APP.RUN_FAILED"; ABORTED: "CLI.APP.ABORTED"; }; } ``` Immutable registry of all error codes used by `@suaveplan/cli`. Each value is a dot-delimited string in the form `..`. ### `CliCode` ```ts type CliCode = | "CLI.PARSE.UNKNOWN_OPTION" | "CLI.PARSE.MISSING_VALUE" | "CLI.PARSE.INVALID_VALUE" | "CLI.PARSE.MISSING_ARGUMENT" | "CLI.PARSE.MISSING_REQUIRED_OPTION" | "CLI.COMMAND.NO_ACTION" | "CLI.COMMAND.UNKNOWN_SUBCOMMAND" | "CLI.APP.RUN_FAILED" | "CLI.APP.ABORTED"; ``` Union of all values in `CLI_CODES`. Use as the type parameter for `SuaveplanError` or in exhaustive switch statements. ### `CliError` ```ts class CliError extends SuaveplanError { public constructor( code: CliCode, messageKey: string, options?: SuaveplanErrorOptions ): CliError; } ``` Typed error for all `@suaveplan/cli` failures. - **`code`** — one of the `CliCode` values; accessible as `err.code` via the base class. - **`messageKey`** — i18n message key passed to the base class for message resolver integration. - **`options.cause`** — optional upstream `Error` for cause chaining; accessible as `err.cause`. - **`options.context`** — optional `Record` with structured diagnostic metadata; accessible as `err.context`. Throws: nothing — this is an Error constructor. ## Implementation Notes `CLI_CODES` is built from three separate `defineCodes()` calls rather than one flat call so that each sub-namespace is isolated. This mirrors the pattern established in `@suaveplan/readline` and keeps future code-set additions within a namespace non-breaking for callers who already destructure `CLI_CODES.PARSE`. The `CliError` constructor comment (`biome-ignore`) documents why the constructor is not "useless" from Biome's perspective: the base `SuaveplanError` constructor is `protected`, so widening it to `public` here is a meaningful override even though the body only calls `super()`. This is the standard pattern across all `@suaveplan/*` packages. No runtime dependencies beyond `@suaveplan/error` are introduced. The `defineCodes` helper produces plain string literals, so the entire module tree-shakes to near zero bytes when errors are not thrown on a given code path.