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