# fsm-error _(no submodules)_ ## Purpose Defines the stable error-code registry and typed error class for the `@suaveplan/fsm` package. Every error thrown by the FSM interpreter, definition validator, and context helpers extends `FSMError`, giving callers a single `instanceof` check and a machine-readable `code` property drawn from `FSM_CODES`. The registry is built with `defineCodes` from `@suaveplan/error`, which guarantees that each code string is unique across the entire `@suaveplan/*` ecosystem and can be compared with `===` without string literals. ## Features - Five stable error codes covering all failure scenarios: `INVALID_DEFINITION`, `INVALID_TRANSITION`, `INVALID_STATE`, `GUARD_FAILED`, `ACTION_ERROR` - `FSMError` extends `SuaveplanError` for narrow discriminated-union typing - Supports optional `cause` and `context` metadata on every error instance - Fully compatible with the `@suaveplan/error` wire-format serialization ## Usage: Basic Example ```ts import { FSMError, FSM_CODES } from '@suaveplan/fsm/errors'; try { machine.send('UNKNOWN_EVENT'); } catch (err) { if (err instanceof FSMError) { console.error(err.code, err.message); // "FSM.INVALID_TRANSITION" "No valid transition for event in current state" } } ``` ## Usage: Advanced Example ```ts import { FSMError, FSM_CODES } from '@suaveplan/fsm/errors'; function handleFSMError(err: unknown): void { if (!(err instanceof FSMError)) throw err; switch (err.code) { case FSM_CODES.INVALID_DEFINITION: console.error('Machine definition is malformed:', err.message); break; case FSM_CODES.INVALID_TRANSITION: console.warn('Event not handled in current state'); break; case FSM_CODES.GUARD_FAILED: console.info('Transition blocked by guard'); break; case FSM_CODES.ACTION_ERROR: console.error('Action threw during transition:', err.cause); break; default: throw err; } } ``` ## API Reference ### `FSM_CODES` ```ts const FSM_CODES: { INVALID_DEFINITION: 'FSM.INVALID_DEFINITION'; INVALID_TRANSITION: 'FSM.INVALID_TRANSITION'; INVALID_STATE: 'FSM.INVALID_STATE'; GUARD_FAILED: 'FSM.GUARD_FAILED'; ACTION_ERROR: 'FSM.ACTION_ERROR'; } ``` Stable string constants for each FSM error domain. Use these instead of raw string comparisons to benefit from TypeScript narrowing. ### `type FSMCode` Union type of all values in `FSM_CODES`. Used as the generic parameter of `FSMError`. ### `class FSMError` ```ts class FSMError extends SuaveplanError { constructor( code: FSMCode, message: string, options?: { cause?: Error; context?: Record } ) } ``` **Parameters:** - `code` — one of the `FSM_CODES` values; stored as `this.code` - `message` — human-readable description of the failure - `options.cause` — underlying error that triggered this one (chained) - `options.context` — arbitrary key/value metadata (state name, event type, etc.) **Throws:** Never (constructor only). ## Implementation Notes The `defineCodes` helper from `@suaveplan/error` namespaces all codes under `"FSM."` to prevent collisions with codes from other packages sharing the same registry. The `as const` assertion on the descriptor object ensures the resulting type is a fully-discriminated union rather than `string`. The `noUselessConstructor` biome lint suppression is intentional: the constructor is required to widen the `protected` base constructor to `public`, which is a documented pattern in this repository for all `SuaveplanError` subclasses.