Initial Commit
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# error-codes
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the stable error-code registry for `@suaveplan/profiler` and the typed `ProfilerError` class consumers throw from every failure path. Codes are registered with `@suaveplan/error`'s `defineCodes` helper so they survive serialisation and module-boundary crossings — consumers discriminate on `error.code` rather than `instanceof`, which keeps the contract portable across worker threads, HTTP wire formats, and language-server log scrapes.
|
||||
|
||||
## Features
|
||||
|
||||
- Seven canonical codes: `INVALID_OPTIONS`, `UNKNOWN_LABEL`, `SAMPLER_ALREADY_RUNNING`, `SAMPLER_NOT_RUNNING`, `MEMORY_ALREADY_RUNNING`, `MEMORY_NOT_RUNNING`, `EXPORT_FAILED`.
|
||||
- Every code namespaced under the `PROFILER.` prefix at registration time.
|
||||
- `ProfilerError` extends `SuaveplanError<ProfilerCode>` so the `code` field narrows against the literal union and `switch (err.code)` is exhaustively type-checked.
|
||||
- Public constructor: `SuaveplanError`'s own constructor is protected, so we delegate via `super(code, message, options)` and set `this.name = "ProfilerError"` so stack frames stay readable.
|
||||
- `ProfilerError` accepts `{ cause?, context? }` — `cause` chains underlying errors, `context` ships structured details to log sinks.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { PROFILER_CODES, ProfilerError } from "@suaveplan/profiler";
|
||||
|
||||
throw new ProfilerError(
|
||||
PROFILER_CODES.INVALID_OPTIONS,
|
||||
"Sampler intervalMs must be positive"
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
try {
|
||||
new Sampler({ intervalMs: -1 });
|
||||
} catch (err) {
|
||||
if (err instanceof ProfilerError) {
|
||||
switch (err.code) {
|
||||
case PROFILER_CODES.INVALID_OPTIONS:
|
||||
logger.warn("config rejected", err.context);
|
||||
break;
|
||||
case PROFILER_CODES.EXPORT_FAILED:
|
||||
metrics.exportFailures.add(1);
|
||||
break;
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `PROFILER_CODES: Readonly<{ INVALID_OPTIONS: "PROFILER.INVALID_OPTIONS", ... }>` — frozen literal-type record.
|
||||
- `type ProfilerCode = (typeof PROFILER_CODES)[keyof typeof PROFILER_CODES]` — discriminated union.
|
||||
- `class ProfilerError extends SuaveplanError<ProfilerCode>` — public `constructor(code, message, options?)`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The registry is built with `defineCodes("PROFILER", [...] as const)` so TypeScript can infer the keys as literal types. Adding a new code requires appending to the `as const` array and to the OpenSpec spec delta — no other change is needed because the union and registry update together. The `ProfilerError` constructor is intentionally minimal: it delegates to `SuaveplanError`, sets `this.name`, and accepts the same options bundle so error logs and OTel span events render correctly out of the box.
|
||||
Reference in New Issue
Block a user