# `error-codes` — `SECRETS_CODES` and `SecretsError` _(no submodules)_ ## Purpose `SECRETS_CODES` is the frozen registry of fully-qualified error codes the API plugin system throws when a plugin tries to read a secret the source cannot supply, or when the host detects a missing required secret during install. Pinning the registry in one place keeps the wire format stable for clients, lets the `@suaveplan/error` i18n resolver translate codes to human messages, and gives every concrete source (env, Bun.secrets, vault) a single canonical set of identifiers to throw. `SecretsError` is the concrete `SuaveplanError` subclass for the secrets domain. It widens the abstract base's `protected` constructor to public so callers can throw without defining a per-call subclass, while still benefiting from `instanceof SecretsError` narrowing the code union to `SecretsCode`. ## Features - Four canonical codes: `SECRET_NOT_FOUND`, `SECRET_REQUIRED_MISSING_AT_START`, `SECRET_INVALID_FORMAT`, `SOURCE_UNAVAILABLE`. - All codes fully-qualified at the `SECRETS.` namespace. - `Object.freeze`d registry — mutation attempts throw in strict mode. - `SecretsError` class with type-level code narrowing. ## Usage: Basic ```ts import { SECRETS_CODES, SecretsError } from "@suaveplan/api-secrets/error-codes"; throw new SecretsError( SECRETS_CODES.SECRET_NOT_FOUND, "error.secrets.not_found", { context: { name: "STRIPE_KEY" } } ); ``` ## Usage: Advanced Pattern-matching on the code union in a host-side error mapper: ```ts import { SECRETS_CODES, type SecretsCode, SecretsError } from "@suaveplan/api-secrets/error-codes"; function toHttpStatus(err: SecretsError): number { const code: SecretsCode = err.code; switch (code) { case SECRETS_CODES.SECRET_NOT_FOUND: return 404; case SECRETS_CODES.SECRET_REQUIRED_MISSING_AT_START: return 503; // install incomplete case SECRETS_CODES.SECRET_INVALID_FORMAT: return 422; case SECRETS_CODES.SOURCE_UNAVAILABLE: return 503; } } ``` ## API Reference - `const SECRETS_CODES` — `Readonly<{ [K in CodeKey]: \`SECRETS.${K}\` }>`; frozen. - `type SecretsCode` — the literal-string union derived from `SECRETS_CODES`. - `class SecretsError extends SuaveplanError` — public constructor `(code, messageKey, options?)`. ## Implementation Notes The registry is built via `defineCodes("SECRETS", [...] as const)` from `@suaveplan/error`. `defineCodes` returns a frozen record so the registry is immutable at runtime; the `as const` on the keys array gives TypeScript the literal-string view it needs to derive `SecretsCode`. The `SecretsError` constructor delegates straight to the `SuaveplanError` base, including the trace-id, context, and clock injection points — every error thrown through `SecretsError` participates in `walkCauses`, `toSpanEvent`, and the redacted wire format. Note that `SuaveplanError` is abstract specifically because every domain should have its own `instanceof`-distinct subclass; do not import `SuaveplanError` directly to throw from this package.