# `errors/errors.ts` _(no submodules)_ ## Purpose Stable error code registry, per-code metadata, and the concrete `ClipboardError` class for the `@suaveplan/clipboard` package. Every error path inside the manager, fallback, permissions, and security modules surfaces one of these codes so consumers can match programmatically without inspecting message strings. Codes are namespaced under `CLIPBOARD.*` and registered via the shared `defineCodes` helper from `@suaveplan/error` so the runtime values, the literal union type, and the metadata table stay in lock-step. ## Features - Eight stable codes: `API_UNAVAILABLE`, `PERMISSION_DENIED`, `FALLBACK_FAILED`, `INSECURE_CONTEXT`, `NO_CONTENT`, `READ_FAILED`, `DOCUMENT_UNAVAILABLE`, `QUEUE_DRAINED`. - Per-code metadata: `httpStatus`, `retryable`, `severity`, `description`. - `ClipboardError extends SuaveplanError` — preserves cause chains, supports OTel span events, and integrates with the project's typed-error contract. - `asClipboardError(code, cause, fallbackMessage)` lifts unknown thrown values into the typed hierarchy at every catch site. ## Usage: Basic ```ts import { CLIPBOARD_CODES, ClipboardError, } from "@suaveplan/clipboard"; try { // ... } catch (cause) { throw new ClipboardError( CLIPBOARD_CODES.READ_FAILED, "Clipboard read rejected", { cause: cause instanceof Error ? cause : new Error(String(cause)) }, ); } ``` ## Usage: Advanced ```ts import { asClipboardError, CLIPBOARD_CODES, CLIPBOARD_ERROR_METADATA, } from "@suaveplan/clipboard"; function decide(err: unknown): { retry: boolean; status: number } { if ( err instanceof Error && "code" in err && typeof (err as { code?: string }).code === "string" && (err as { code: string }).code.startsWith("CLIPBOARD.") ) { const meta = CLIPBOARD_ERROR_METADATA[ (err as { code: keyof typeof CLIPBOARD_ERROR_METADATA }) .code ]; return { retry: meta.retryable, status: meta.httpStatus }; } const lifted = asClipboardError( CLIPBOARD_CODES.READ_FAILED, err, "Unknown clipboard failure.", ); return { retry: lifted.metadata.retryable, status: lifted.metadata.httpStatus, }; } ``` ## API Reference ### `CLIPBOARD_CODES` `Readonly, "CLIPBOARD.">>` produced by `defineCodes`. The runtime values are namespaced strings; the type infers a literal union for exhaustive matching. ### `CLIPBOARD_ERROR_METADATA` `Readonly>` — frozen map from each code to its `httpStatus`, `retryable`, `severity`, and `description` fields. ### `ClipboardCodeMetadata` Interface with `httpStatus: number`, `severity: "info" | "warning" | "error"`, `retryable: boolean`, `description: string`. ### `ClipboardError` Concrete subclass of `SuaveplanError`. Constructor signature: `new ClipboardError(code, message, options?)`. Exposes a `.metadata` getter that returns the row from `CLIPBOARD_ERROR_METADATA`. ### `asClipboardError(code, cause, fallbackMessage)` Lifts an arbitrary `unknown` thrown value into a `ClipboardError`, preserving the cause chain. Uses `cause.message` when available and `fallbackMessage` otherwise. Always returns a `ClipboardError` with the supplied code. ## Implementation Notes The package version of `defineCodes` is the canonical helper from `@suaveplan/error`; every package uses the same pattern so cross- cutting tooling (registry validators, retention checks, OpenSpec conformance) can introspect every namespace identically. Codes are intentionally namespaced strings rather than enums so they remain JSON- serialisable and stable across versions. The metadata table is `Object.freeze`-d so mutation is a typecheck error and a runtime error; reviewers can diff additions in pull requests without worrying about silent rewrites.