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,63 @@
# error-codes
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Defines the stable, machine-readable error namespace for `@suaveplan/campaigns`. Every failure path in the package — from invalid options at construction time, through state-machine violations during a send, to missing records and store contract breaches — produces a `CampaignsError` whose `code` is drawn from the `CAMPAIGNS_CODES` registry.
Centralising the registry here keeps the error namespace decoupled from any one feature module. Downstream consumers can pattern-match on the code constants instead of importing concrete error classes, which keeps deserialised errors (over the wire, across worker boundaries) just as switchable as in-process ones.
## Features
- `CAMPAIGNS_CODES` literal map produced by `defineCodes("CAMPAIGNS", [...])`.
- `CampaignsCode` discriminating union literal type derived from the registry.
- `CampaignsError extends SuaveplanError<CampaignsCode>` with an explicit public constructor so `new CampaignsError(...)` is allowed at any call site.
- Eight initial codes covering construction, input validation, state transitions, missing records, store breaches, batch + throttle config validation, and workflow failures.
- Codes are namespaced under the `CAMPAIGNS.` prefix so they never clash with codes from sibling packages.
## Usage: Basic
```ts
import { CAMPAIGNS_CODES, CampaignsError } from "@suaveplan/campaigns";
throw new CampaignsError(
CAMPAIGNS_CODES.CAMPAIGN_NOT_FOUND,
"Campaign not found: c-42",
{ context: { id: "c-42" } }
);
```
## Usage: Advanced
Discriminating in consumer code without an `instanceof` chain:
```ts
import { CAMPAIGNS_CODES, CampaignsError } from "@suaveplan/campaigns";
try {
await engine.send(id);
} catch (err) {
if (!(err instanceof CampaignsError)) throw err;
switch (err.code) {
case CAMPAIGNS_CODES.CAMPAIGN_NOT_FOUND:
return { kind: "not-found" as const };
case CAMPAIGNS_CODES.INVALID_TRANSITION:
return { kind: "conflict" as const };
default:
throw err;
}
}
```
## API Reference
- `CAMPAIGNS_CODES` — readonly literal map of `KEY -> "CAMPAIGNS.KEY"` strings.
- `CampaignsCode` — `typeof CAMPAIGNS_CODES[keyof typeof CAMPAIGNS_CODES]`.
- `CampaignsError(code, message, options?)` — public constructor delegating to `SuaveplanError`. `options.cause` chains an underlying error; `options.context` attaches a structured payload.
## Implementation Notes
`SuaveplanError`'s base constructor is protected, so without the explicit `public constructor` here, `new CampaignsError(...)` would fail with TS2674. The constructor sets `this.name = "CampaignsError"` so stack traces are self-describing. The `code` field narrows against `CampaignsCode`, which means consumers get exhaustiveness checking on `switch` statements with `noFallthroughCasesInSwitch` enabled.