first commit
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# `error-codes` — stable error registry for `@suaveplan/react-packer`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the canonical error-code registry and concrete error class for
|
||||
the React-tier packer companion. Every failure mode surfaced through
|
||||
`usePackedResource` and its variants funnels through `ReactPackerError`,
|
||||
which extends `@suaveplan/error`'s `SuaveplanError` so consumers get
|
||||
cause-chain traversal, OTel span-event tagging, and i18n message
|
||||
resolution for free.
|
||||
|
||||
This module is the single source of truth for `REACT_PACKER_*` codes —
|
||||
no other file may invent new ones. Hooks and the provider import the
|
||||
exported constants and class to raise typed errors; tests assert on the
|
||||
code constants rather than string-comparing message keys.
|
||||
|
||||
## Features
|
||||
|
||||
- `REACT_PACKER_CODES` — frozen registry of three codes: `LOAD_FAILED`,
|
||||
`FONT_LOAD_FAILED`, `ABORTED`.
|
||||
- `ReactPackerError` — `SuaveplanError` subclass with a unique brand
|
||||
`Symbol` so cross-realm `instanceof` failures still permit safe
|
||||
discrimination via `ReactPackerError.is(value)`.
|
||||
- `cause` preservation — when a hook wraps a `PackerBrowserError` or a
|
||||
`DOMException` from `document.fonts.load`, the original error rides on
|
||||
`.cause` for downstream debugging and OTel attribute capture.
|
||||
- Stable shape — adding new codes requires a new OpenSpec change so the
|
||||
public registry never drifts mid-version.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { REACT_PACKER_CODES, ReactPackerError } from "@suaveplan/react-packer";
|
||||
|
||||
try {
|
||||
await loadSomething();
|
||||
} catch (cause) {
|
||||
throw new ReactPackerError(
|
||||
REACT_PACKER_CODES.LOAD_FAILED,
|
||||
"react-packer.load-failed",
|
||||
{ cause }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { REACT_PACKER_CODES, ReactPackerError } from "@suaveplan/react-packer";
|
||||
|
||||
function onError(value: unknown): string {
|
||||
if (ReactPackerError.is(value)) {
|
||||
switch (value.code) {
|
||||
case REACT_PACKER_CODES.LOAD_FAILED:
|
||||
return "Could not unpack the resource.";
|
||||
case REACT_PACKER_CODES.FONT_LOAD_FAILED:
|
||||
return "Font failed to load; falling back to system font.";
|
||||
case REACT_PACKER_CODES.ABORTED:
|
||||
return "Cancelled.";
|
||||
default:
|
||||
return "Unexpected error.";
|
||||
}
|
||||
}
|
||||
return "Unknown error.";
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `REACT_PACKER_CODES` — `Readonly<{ LOAD_FAILED, FONT_LOAD_FAILED, ABORTED }>`
|
||||
registered via `@suaveplan/error`'s `defineCodes("REACT_PACKER", ...)`.
|
||||
- `ReactPackerErrorCode` — union of the values of `REACT_PACKER_CODES`.
|
||||
- `ReactPackerError(code, messageKey, options?)` — constructor accepts
|
||||
the registered code, an i18n message key, and the standard
|
||||
`SuaveplanErrorOptions` (including `cause` and `params`).
|
||||
- `ReactPackerError.is(value: unknown): value is ReactPackerError` —
|
||||
returns `true` only when `value` is a real `ReactPackerError` carrying
|
||||
the brand symbol.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- The brand `Symbol` is module-local, so passing a forged object with
|
||||
the same shape will not satisfy `is(...)`. This is intentional —
|
||||
duck-typed substitutes break OTel reporting and cause chains.
|
||||
- `SuaveplanError` already pins `.code` and `.message` (resolved from
|
||||
the messageKey) as read-only fields; subclasses do not need to
|
||||
redeclare them.
|
||||
- The brand assignment in the constructor is what makes `super(code, ...)`
|
||||
safe — TypeScript's definite-assignment analysis is satisfied by the
|
||||
`public readonly [BRAND]: true` field plus the constructor write.
|
||||
Reference in New Issue
Block a user