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,61 @@
# `error-codes.ts` — webhook plugin error registry
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Defines the ten stable `WEBHOOK_*` error codes raised by the api-plugin-webhook package and the concrete `WebhookError` class used to surface them. Every failure path in the plugin — invalid options, missing endpoints, exhausted retries, dead-letter writes, route-prefix collisions, missing `ServiceRegistry` slots, inactive endpoints, tenant mismatches, missing subscriptions, and persistence-layer failures — funnels through this module so consumers can branch on the typed `error.code` string without reaching for `instanceof` for individual subclasses.
## Features
- Stable string codes registered through `@suaveplan/error`'s `defineCodes("WEBHOOK", [...])` (process-wide deduplication, OTel span-event compatible).
- Concrete `WebhookError extends SuaveplanError<WebhookErrorCode>` so `instanceof WebhookError` narrows `code` to the typed union.
- Re-exported under the package barrel and at the `./error-codes/error-codes` subpath for tree-shaking.
## Usage: Basic
```ts
import { WEBHOOK_CODES, WebhookError } from "@suaveplan/api-plugin-webhook/error-codes/error-codes";
throw new WebhookError(
WEBHOOK_CODES.ENDPOINT_NOT_FOUND,
"endpoint missing",
{ context: { endpointId: "abc" } }
);
```
## Usage: Advanced
```ts
import { WEBHOOK_CODES, WebhookError } from "@suaveplan/api-plugin-webhook";
try {
await webhookService.send("missing", "order.created", {});
} catch (err) {
if (err instanceof WebhookError) {
switch (err.webhookCode) {
case WEBHOOK_CODES.ENDPOINT_NOT_FOUND:
return ctx.json({ error: "unknown endpoint" }, 404);
case WEBHOOK_CODES.DELIVERY_EXHAUSTED:
return ctx.json({ error: "delivery failed, see dead letter" }, 502);
case WEBHOOK_CODES.INACTIVE_ENDPOINT:
return ctx.json({ error: "endpoint disabled" }, 409);
default:
throw err;
}
}
throw err;
}
```
## API Reference
- `WEBHOOK_CODES` — readonly string-literal map. Each property name is one of the ten registered codes and the value is the `"WEBHOOK_<NAME>"` string carried on `WebhookError.code`.
- `WebhookErrorCode` — string-literal union derived from `typeof WEBHOOK_CODES[keyof typeof WEBHOOK_CODES]`.
- `WebhookError` — extends `SuaveplanError<WebhookErrorCode>`. Constructor signature: `new WebhookError(code, message, options?)` where `options` accepts `{ cause?, context?, status?, retryable?, exposeMessage? }` via `SuaveplanErrorOptions`. Exposes `webhookCode` (alias for the typed `code`) so consumers can branch without a cast.
## Implementation Notes
The ten codes were chosen to cover every distinct failure mode the plugin can surface to a caller: factory-level (`INVALID_INPUT`), service-resolution (`SERVICE_NOT_AVAILABLE`), route-registration (`ROUTE_PREFIX_COLLISION`), persistence (`STORE_ERROR`), authorization (`TENANT_MISMATCH`), state (`INACTIVE_ENDPOINT`, `ENDPOINT_NOT_FOUND`, `EVENT_NOT_SUBSCRIBED`), and delivery (`DELIVERY_EXHAUSTED`, `DEAD_LETTER_WRITE_FAILED`). Adding a new code requires a follow-up OpenSpec change so the spec-conformance test (`api-plugin-webhook.spec-conformance.test.ts`) stays in lock-step with the registry. The `defineCodes` factory throws on registry collision at module load — guarantees one canonical owner per code.