# `error-codes` — `MIGRATION_*` registry and `MigrationError` _(no submodules)_ ## Purpose Defines the stable, namespaced error registry for `@suaveplan/api-migrations`. Every public failure path in the package raises a `MigrationError` carrying exactly one of the six `MIGRATION.*` codes defined here. The codes are authored once at draft time and may not be renumbered or renamed without an OpenSpec change, so consumers may branch on the literal string values across versions. The pairing of `defineCodes("MIGRATION", [...])` (from `@suaveplan/error`) with a typed `SuaveplanError` subclass keeps the surface narrow: the runtime sees a frozen registry object, TypeScript sees a literal union, and consumers get an `instanceof MigrationError` narrowing the `code` field to `MigrationErrorCode`. ## Features - Frozen registry of exactly six codes. - `MigrationError` is a public-constructor subclass of `SuaveplanError`. - `instanceof MigrationError` narrows `error.code` to `MigrationErrorCode`. - The `migrationCode` field is a synonym for `code` typed as the literal union, useful inside generic helpers that have already widened `code`. - Every code is exercised by the package's spec-conformance test. ## Usage: Basic Example ```ts import { MIGRATION_CODES, MigrationError, } from "@suaveplan/api-migrations/error-codes/error-codes"; throw new MigrationError( MIGRATION_CODES.DIRECTORY_NOT_FOUND, "Migration directory does not exist: ./db/migrations", { context: { dir: "./db/migrations" } } ); ``` ## Usage: Advanced Example ```ts import { MIGRATION_CODES, MigrationError, type MigrationErrorCode, } from "@suaveplan/api-migrations/error-codes/error-codes"; function isRecoverable(code: MigrationErrorCode): boolean { return ( code === MIGRATION_CODES.CHECKSUM_DRIFT || code === MIGRATION_CODES.INVALID_FILE_NAME ); } try { await runner.runFromDirectory("./db/migrations"); } catch (err) { if (err instanceof MigrationError && isRecoverable(err.code)) { // Operator-fixable conditions: stale file or rename. console.error("Recoverable migration error:", err.code, err.context); } else { throw err; } } ``` ## API Reference - `MIGRATION_CODES` — frozen registry `{ TABLE_BOOTSTRAP_FAILED, APPLY_FAILED, CHECKSUM_DRIFT, DIRECTORY_NOT_FOUND, INVALID_FILE_NAME, ROLLBACK_NOT_SUPPORTED }`, each value the literal string of the form `"MIGRATION."`. - `type MigrationErrorCode` — union of the six literal strings. - `class MigrationError extends SuaveplanError` — constructor `(code, message, options?)`. `options.context` and `options.cause` are forwarded to the base class. `migrationCode` is a typed alias of `code`. ## Implementation Notes - The registry is authored as `as const` and passed to `defineCodes`, which freezes the resulting object and returns a strongly typed map. Renaming or renumbering codes is a breaking change that must be made through OpenSpec. - `MigrationError`'s constructor is `public` so call sites may instantiate it directly; `SuaveplanError`'s constructor is `protected` and would otherwise refuse construction outside of subclasses. - `migrationCode` exists in addition to `code` because some generic helpers (logging, OTel attribute attachment) widen the type to `string` for ergonomics; tests and downstream consumers that want the narrow union read `migrationCode` instead. - Every code is thrown from at least one production call site — see `src/api-migrations.spec-conformance.test.ts` for the inventory.