# error-codes _(no submodules)_ ## 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` 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` — 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.