first commit
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user