# `TENANT_PROVIDER_CODES` — stable error registry _(no submodules)_ ## Purpose `@suaveplan/api-tenant-provider` raises every failure through a single `SuaveplanError` subclass — `TenantProviderError` — and every instance carries a code from the frozen `TENANT_PROVIDER_CODES` registry. The registry exists so consumers can branch on a stable string literal (`error.code === "TENANT_PROVIDER.INVALID_CURSOR"`) without coupling to the package's class hierarchy or sniffing message text. Because tenant enumeration is consumed by very different concerns (per-tenant cron fan-out, admin dashboards, background reconciliation, cache warmers), a small set of well-named codes is more useful than a large catalogue: callers either retry on `SOURCE_UNAVAILABLE`, fix caller bugs on `INVALID_CURSOR`, or treat the absent record as expected on `TENANT_NOT_FOUND`. ## Features - `defineCodes("TENANT_PROVIDER", [...])` produces a frozen registry; new entries are an OpenSpec change. - `TenantProviderError extends SuaveplanError` so `instanceof TenantProviderError` narrows the `code` field. - Three codes: `TENANT_NOT_FOUND`, `SOURCE_UNAVAILABLE`, `INVALID_CURSOR`. - Inherits cause-chain, redaction, OTel span-event adapter from `@suaveplan/error`. ## Usage: Basic ```ts import { TENANT_PROVIDER_CODES, TenantProviderError, } from "@suaveplan/api-tenant-provider/error-codes"; throw new TenantProviderError( TENANT_PROVIDER_CODES.TENANT_NOT_FOUND, "tenant t-42 is not registered", ); ``` ## Usage: Advanced ```ts import { TenantProviderError, TENANT_PROVIDER_CODES, } from "@suaveplan/api-tenant-provider/error-codes"; try { for await (const t of provider.list({ cursor })) { // ... } } catch (err) { if ( err instanceof TenantProviderError && err.code === TENANT_PROVIDER_CODES.INVALID_CURSOR ) { // The caller passed a cursor not produced by `list()` — reset // and start a fresh iteration instead of crashing the job. for await (const t of provider.list()) { // ... } } else { throw err; } } ``` ## API Reference - `TENANT_PROVIDER_CODES`: `Readonly<{ TENANT_NOT_FOUND: "TENANT_PROVIDER.TENANT_NOT_FOUND"; SOURCE_UNAVAILABLE: "TENANT_PROVIDER.SOURCE_UNAVAILABLE"; INVALID_CURSOR: "TENANT_PROVIDER.INVALID_CURSOR" }>`. - `TenantProviderErrorCode`: the union of those three string literals. - `class TenantProviderError extends SuaveplanError` with `constructor(code, message, options?)` and public `readonly tenantProviderCode`. ## Implementation Notes The codes are defined via `defineCodes("TENANT_PROVIDER", [...] as const)` so the `TENANT_PROVIDER.` prefix is forwarded by the registry helper — the array entries are bare names. The resulting object is frozen at construction and the type is widened to the union of every namespaced literal. The `tenantProviderCode` field on the error mirrors `code` for ergonomic narrowing in consumer code that already imports the class but not the code union.