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