Initial Commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
# error-codes
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`error-codes` exports the canonical stable error-code registry used by every other module in `@suaveplan/test-vite`. The registry is built with `@suaveplan/error`'s `defineCodes` so each code value becomes a namespaced string of the form `TEST_VITE.<REASON>`. This namespace survives module boundaries, structured cloning, RPC boundaries, and JSON serialisation, so callers can discriminate on `error.code` rather than relying on prototype chains. The companion `TestViteError` class extends `SuaveplanError<TestViteCode>` so static analysis narrows `err.code` to the literal union of registered codes.
|
||||
|
||||
## Features
|
||||
|
||||
- 8-code namespaced registry: `INVALID_OPTIONS`, `MISSING_ENTRY`, `TREE_SHAKE_VIOLATION`, `SIZE_BUDGET_EXCEEDED`, `SNAPSHOT_MISSING`, `PORT_EXHAUSTED`, `PORT_NOT_HELD`, `HMR_TIMEOUT`.
|
||||
- `TestViteError` class extending `SuaveplanError<TestViteCode>` with a public constructor.
|
||||
- Structured `details` payload propagated as the `SuaveplanError` `context` field.
|
||||
- Cause-chain support via the standard `Error.cause` constructor option.
|
||||
- No marketing language — each code names a concrete, reachable failure mode.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { TEST_VITE_CODES, TestViteError } from "@suaveplan/test-vite/error-codes";
|
||||
|
||||
try {
|
||||
doSomething();
|
||||
} catch (err) {
|
||||
if (err instanceof TestViteError && err.code === TEST_VITE_CODES.INVALID_OPTIONS) {
|
||||
console.error("bad options", err.details);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Discriminate on the namespaced code value directly so the handler survives RPC and serialisation:
|
||||
|
||||
```ts
|
||||
import { TEST_VITE_CODES } from "@suaveplan/test-vite/error-codes";
|
||||
|
||||
function isTestViteError(err: unknown): err is { code: string; details: Record<string, unknown> } {
|
||||
return typeof err === "object" && err !== null && typeof (err as { code?: unknown }).code === "string";
|
||||
}
|
||||
|
||||
function classify(err: unknown): "retry" | "abort" {
|
||||
if (!isTestViteError(err)) return "abort";
|
||||
switch (err.code) {
|
||||
case TEST_VITE_CODES.PORT_EXHAUSTED:
|
||||
case TEST_VITE_CODES.HMR_TIMEOUT:
|
||||
return "retry";
|
||||
default:
|
||||
return "abort";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `TEST_VITE_CODES` — `Readonly<Record<string, TestViteCode>>` built via `defineCodes("TEST_VITE", [...])`.
|
||||
- `TestViteCode` — string literal union of every registered code.
|
||||
- `TestViteError extends SuaveplanError<TestViteCode>` — `new TestViteError(code, message, { cause?, details? })`. Exposes `code: TestViteCode`, `message: string`, `details: Record<string, unknown>`, and inherits `timestamp`, `name`, `cause` from `SuaveplanError` / `Error`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The constructor passes the `details` payload to `SuaveplanError` as `context` so the OTel span-event adapter picks it up automatically. We mirror the payload on a public `details` field for ergonomic access from non-TypeScript consumers. `cause` is forwarded only when supplied so the standard `Error.prototype.cause` behaviour stays clean.
|
||||
Reference in New Issue
Block a user