# error-codes _(no submodules)_ ## Purpose Defines the stable error-code registry and concrete error class for `@suaveplan/api-plugin-events`. Every failure path in the plugin — configuration validation, lifecycle wiring, repository write paths, route-handler authorisation — raises an `EventsPluginError` carrying exactly one of the twelve `EVENTS_PLUGIN.*` codes. The registry is the contract: consumers branch on `error.code === EVENTS_PLUGIN_CODES.RSVP_NOT_FOUND` and receive `EventsPluginErrorCode` narrowing for free. The namespace literal is `"EVENTS_PLUGIN"` rather than the obvious `"EVENTS"` to avoid a hard collision with `@suaveplan/events` (the typed event-bus already shipped ). The event-bus library owns the `EVENTS_*` prefix; this plugin uses the longer prefix so both registries can coexist in the same project without either having to rename codes downstream. ## Features - 12 documented codes covering every public failure surface. - `EventsPluginError` extends `SuaveplanError` so `instanceof` narrows `error.code` to `EventsPluginErrorCode`. - Side-effect-free import — `import "./error-codes.js"` for code registry registration with zero runtime cost. - `cause` chain + `context` bag forwarded to the `@suaveplan/error` base class for OTel span events and i18n resolution. ## Usage: Basic Example ```ts import { EVENTS_PLUGIN_CODES, EventsPluginError, } from "@suaveplan/api-plugin-events"; throw new EventsPluginError( EVENTS_PLUGIN_CODES.EVENT_NOT_FOUND, "Event not found" ); ``` ## Usage: Advanced Example ```ts import { EVENTS_PLUGIN_CODES, EventsPluginError, type EventsPluginErrorCode, } from "@suaveplan/api-plugin-events"; function describe(code: EventsPluginErrorCode): string { switch (code) { case EVENTS_PLUGIN_CODES.INVALID_CONFIG: return "configuration rejected by Zod"; case EVENTS_PLUGIN_CODES.EVENT_CREATE_FAILED: return "adapter returned no row from CREATE event"; default: return code; } } try { // ... } catch (err) { if (err instanceof EventsPluginError) { const label = describe(err.code); // forward to logger / OTel console.error(label, err.context, err.cause); } } ``` ## API Reference ### `EVENTS_PLUGIN_CODES` A frozen object mapping each code key to its stable string value: - `INVALID_CONFIG` — Zod-validated options were rejected. - `SERVICE_NOT_AVAILABLE` — required `ServiceRegistry` slot missing. - `ROUTE_PREFIX_COLLISION` — `onReady` would shadow existing routes. - `EVENT_CREATE_FAILED` / `EVENT_UPDATE_FAILED` — adapter returned no row. - `RSVP_CREATE_FAILED` / `RSVP_UPDATE_FAILED` — adapter returned no row. - `RSVP_NOT_FOUND` / `EVENT_NOT_FOUND` — lookup miss. - `UNAUTHENTICATED` — `c.get("user")` was missing on a route. - `FORBIDDEN` — non-creator hit a mutating endpoint. - `INVITE_LIMIT_EXCEEDED` — `user_ids` length exceeded the runtime cap. ### `EventsPluginErrorCode` Union of all values in `EVENTS_PLUGIN_CODES` — useful for exhaustive `switch` over caught errors. ### `EventsPluginError` ```ts class EventsPluginError extends SuaveplanError { constructor( code: EventsPluginErrorCode, message: string, options?: SuaveplanErrorOptions ); readonly eventsPluginCode: EventsPluginErrorCode; } ``` ## Implementation Notes The 12-code registry is fixed for `0.x` — adding a code is a minor bump, removing or renaming one is a major bump. The `error-codes.test.ts` reflects over the registry and grep-asserts each value reaches a `throw new EventsPluginError` call site under `src/`; that test is the canonical proof that no code is a dangling declaration. Removing a code to make the test pass is explicitly banned by `AGENTS.md` §2c — wire the missing throw site instead.