first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
# error-codes
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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<EventsPluginErrorCode> {
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.