first commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# `error-codes`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the stable `SERVER_KEYS_*` error-code registry used throughout
|
||||
`@suaveplan/server-keys`. Each code is a namespaced string registered via
|
||||
`defineCodes("SERVER_KEYS", ...)` from `@suaveplan/error`, so the global
|
||||
error registry is aware of every code the package may throw the moment
|
||||
this module is imported. Every public failure path in the package — vault
|
||||
decrypt, password mismatch, packet integrity, chain verify, license
|
||||
delegation, CLI input validation, cooperative abort — raises a
|
||||
`ServerKeysError` with one of these codes, never a bare `Error`.
|
||||
|
||||
The registry is part of the package contract: tests assert that every
|
||||
declared code is raised from at least one production call site, and the
|
||||
spec-conformance test enumerates the registry to keep it from drifting.
|
||||
|
||||
## Features
|
||||
|
||||
- 10 stable codes covering vault, packet, license, input, and abort paths.
|
||||
- `ServerKeysError extends SuaveplanError<ServerKeysErrorCode>` so
|
||||
`instanceof` narrows the `.code` field to the registry's literal union.
|
||||
- Side-effect registration with the global `@suaveplan/error` table — any
|
||||
consumer that imports `@suaveplan/server-keys/error-codes/error-codes`
|
||||
picks up the codes globally.
|
||||
- `serverKeysCode` accessor mirrors `code` for ergonomic narrowing.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
SERVER_KEYS_CODES,
|
||||
ServerKeysError,
|
||||
} from "@suaveplan/server-keys/error-codes/error-codes";
|
||||
|
||||
throw new ServerKeysError(
|
||||
SERVER_KEYS_CODES.VAULT_NOT_FOUND,
|
||||
"Vault file does not exist at /etc/suaveplan/root.vault",
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Chain a cause through the constructor and dispatch on the code in a
|
||||
top-level handler:
|
||||
|
||||
```ts
|
||||
import {
|
||||
SERVER_KEYS_CODES,
|
||||
ServerKeysError,
|
||||
type ServerKeysErrorCode,
|
||||
} from "@suaveplan/server-keys/error-codes/error-codes";
|
||||
|
||||
try {
|
||||
await prepareFileCommand(...);
|
||||
} catch (err) {
|
||||
if (err instanceof ServerKeysError) {
|
||||
const code: ServerKeysErrorCode = err.code;
|
||||
if (code === SERVER_KEYS_CODES.PACKET_INTEGRITY_FAILED) {
|
||||
// re-pack with a different signing key
|
||||
}
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Re-throw with cause chain preserved
|
||||
throw new ServerKeysError(
|
||||
SERVER_KEYS_CODES.VAULT_DECRYPT_FAILED,
|
||||
"Failed to decrypt root vault",
|
||||
{ cause: underlying, context: { vaultPath: "/etc/root.vault" } },
|
||||
);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `SERVER_KEYS_CODES` — frozen record of code constants.
|
||||
- `ServerKeysErrorCode` — union of the registry's string-literal values.
|
||||
- `class ServerKeysError extends SuaveplanError<ServerKeysErrorCode>` —
|
||||
concrete error class with `.code`, `.serverKeysCode`, `.cause`,
|
||||
`.context` (inherited from `SuaveplanError`).
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`defineCodes` returns a frozen object whose keys map to the namespaced
|
||||
string codes (e.g. `SERVER_KEYS_CODES.VAULT_NOT_FOUND === "SERVER_KEYS.VAULT_NOT_FOUND"`).
|
||||
The cast through `SuaveplanError<ServerKeysErrorCode>` keeps the literal
|
||||
narrowing intact across error-catch boundaries. The class deliberately
|
||||
does not introduce extra behavior beyond the discriminator field — error
|
||||
shaping, redaction, and OTel span-event adapters live in
|
||||
`@suaveplan/error`.
|
||||
Reference in New Issue
Block a user