3.6 KiB
3.6 KiB
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.
MigrationErroris a public-constructor subclass ofSuaveplanError.instanceof MigrationErrornarrowserror.codetoMigrationErrorCode.- The
migrationCodefield is a synonym forcodetyped as the literal union, useful inside generic helpers that have already widenedcode. - Every code is exercised by the package's spec-conformance test.
Usage: Basic Example
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
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.<NAME>".type MigrationErrorCode— union of the six literal strings.class MigrationError extends SuaveplanError<MigrationErrorCode>— constructor(code, message, options?).options.contextandoptions.causeare forwarded to the base class.migrationCodeis a typed alias ofcode.
Implementation Notes
- The registry is authored as
as constand passed todefineCodes, 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 ispublicso call sites may instantiate it directly;SuaveplanError's constructor isprotectedand would otherwise refuse construction outside of subclasses.migrationCodeexists in addition tocodebecause some generic helpers (logging, OTel attribute attachment) widen the type tostringfor ergonomics; tests and downstream consumers that want the narrow union readmigrationCodeinstead.- Every code is thrown from at least one production call site — see
src/api-migrations.spec-conformance.test.tsfor the inventory.