3.0 KiB
error-codes
(no submodules)
Purpose
The error-codes module defines the seven stable TENANT.* failure codes
shipped by @suaveplan/api-tenant and the concrete TenantError
class that carries them. Every public failure path in the package —
resolver lookups, middleware status gating, rate-limit enforcement,
input validation, and lookup timeouts — raises a TenantError with
one of these codes so consumers can switch on the string value
without depending on a class-instanceof check.
The registry uses defineCodes("TENANT", [...]) from
@suaveplan/error, which freezes the object and produces
"TENANT.NOT_FOUND"-style stable identifiers. Each code is sized to a
specific operational outcome so log aggregators and on-call dashboards
can group incidents accurately rather than collapsing every failure
under a single bucket.
Features
- Exactly seven
TENANT.*codes:NOT_FOUND,SUSPENDED,PENDING,RESOLUTION_FAILED,RATE_LIMITED,INVALID_INPUT,LOOKUP_TIMEOUT. - Frozen registry —
Object.isFrozen(TENANT_CODES)istrue. TenantError extends SuaveplanError<TenantErrorCode>— the generic parameter narrows.codefromstringto the discriminated union.- A duplicate
.tenantCodefield is exposed alongside.codeso callers writing structural assertions (error.tenantCode === ...) do not have to widen the parent's type parameter. SuaveplanErrorOptionsflows through to supportcause,context, redactable payloads, and OTel span-event adapter integration.
Usage: Basic
import { TENANT_CODES, TenantError } from "@suaveplan/api-tenant";
throw new TenantError(TENANT_CODES.NOT_FOUND, "Tenant 'acme' not found");
Usage: Advanced
Threading a cause and structured context for OTel ingestion:
import { TENANT_CODES, TenantError } from "@suaveplan/api-tenant";
try {
await db.query("SELECT * FROM tenants WHERE slug = $1", ["acme"]);
} catch (cause) {
throw new TenantError(
TENANT_CODES.RESOLUTION_FAILED,
"Tenant lookup failed",
{
cause: cause instanceof Error ? cause : new Error(String(cause)),
context: { resolver: "subdomain", input: "acme" },
}
);
}
API Reference
TENANT_CODES— frozenRecord<string, "TENANT.${string}">mapping short keys (NOT_FOUNDetc.) to dotted identifiers.TenantErrorCode— discriminated string union over(typeof TENANT_CODES)[keyof typeof TENANT_CODES].class TenantError extends SuaveplanError<TenantErrorCode>— constructor(code, message, options?). Public.tenantCodefield mirrors.code.
Implementation Notes
The constructor widens visibility to public because
SuaveplanError's constructor is protected for the base class only.
Every shipped subclass (PluginError, TenantError, etc.)
follows the same shape so consumers can swap subclasses without
adjusting call sites. The tenantCode mirror field avoids forcing
callers to write error.code as TenantErrorCode when narrowing.