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,99 @@
# errors/codes
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
This module declares the stable error-code registry for
`@suaveplan/broadcast-channel`. Every error the package throws surfaces one
of four codes under the `BROADCAST_CHANNEL.*` namespace so downstream
consumers — loggers, problem+json responders, retry wrappers, i18n resolvers
— can map the failure to a retry policy, HTTP status, or translation key
without re-implementing the classifier.
The registry is built via `defineCodes` from `@suaveplan/error`, which yields
a frozen `{ REASON: "BROADCAST_CHANNEL.REASON" }` record at compile time. The
literal-typed union `BroadcastChannelErrorCode` is preserved through the
public surface, so `instanceof BroadcastChannelError` narrows cleanly and
exhaustive `switch (err.code)` blocks stay type-checkable.
## Features
- Four reasons: `CHANNEL_CLOSED`, `MESSAGE_MALFORMED`, `PAYLOAD_TOO_LARGE`, `STORAGE_FAILED`.
- Four typed subclasses extending `SuaveplanError<BroadcastChannelErrorCode>`.
- Every code is thrown from at least one production code path (tested).
- Optional context carriers (`sizeBytes`, `maxBytes`) on the payload-too-large variant.
- `BroadcastChannelError` abstract base for ergonomic `instanceof` checks.
## Usage: Basic
```ts
import {
BROADCAST_CHANNEL_CODES,
BroadcastChannelClosedError,
} from "@suaveplan/broadcast-channel";
try {
channel.send("greet", "hi");
} catch (err) {
if (
err instanceof BroadcastChannelClosedError &&
err.code === BROADCAST_CHANNEL_CODES.CHANNEL_CLOSED
) {
// open the channel first
}
}
```
## Usage: Advanced
```ts
import {
BROADCAST_CHANNEL_CODES,
BroadcastChannelError,
type BroadcastChannelErrorCode,
} from "@suaveplan/broadcast-channel";
function classify(err: unknown): "retry" | "drop" | "alert" {
if (!(err instanceof BroadcastChannelError)) return "alert";
const code: BroadcastChannelErrorCode = err.code;
switch (code) {
case BROADCAST_CHANNEL_CODES.CHANNEL_CLOSED:
return "retry";
case BROADCAST_CHANNEL_CODES.MESSAGE_MALFORMED:
return "drop";
case BROADCAST_CHANNEL_CODES.PAYLOAD_TOO_LARGE:
return "drop";
case BROADCAST_CHANNEL_CODES.STORAGE_FAILED:
return "alert";
default:
return "alert";
}
}
```
## API Reference
- `const BROADCAST_CHANNEL_CODES` — frozen `{ readonly CHANNEL_CLOSED, MESSAGE_MALFORMED, PAYLOAD_TOO_LARGE, STORAGE_FAILED }` mapped to namespaced strings.
- `type BroadcastChannelErrorCode` — union of every code string.
- `abstract class BroadcastChannelError extends SuaveplanError<BroadcastChannelErrorCode>`.
- `class BroadcastChannelClosedError` — `send` on a not-open / closed channel.
- `class BroadcastChannelMessageMalformedError` — Zod validation failure at the boundary.
- `class BroadcastChannelPayloadTooLargeError` — outbound payload over `maxMessageBytes`. Optional `sizeBytes` / `maxBytes` opts populate `context`.
- `class BroadcastChannelStorageFailedError` — fallback transport `StorageLike` rejected.
## Implementation Notes
`defineCodes` returns a `Readonly<Record<Reason, "Namespace.Reason">>` so the
output object can be passed straight into `Object.freeze` consumers and the
keys typecheck as `BroadcastChannelErrorCode`. Each subclass routes through
`pickOpts` to strip `undefined` fields out of `SuaveplanErrorOptions` so the
underlying `SuaveplanError` constructor sees only the keys the caller
explicitly set — this matters for the OTel `toSpanEvent` adapter, which omits
absent attributes rather than emitting `null`. The
`BroadcastChannelPayloadTooLargeError` constructor merges `sizeBytes` /
`maxBytes` into the user-supplied `context` so log lines and span attributes
carry both the offender's size and the configured budget without the caller
having to remember to attach them.