3.0 KiB
error-codes
(no submodules)
Purpose
Defines the stable error-code registry for
@suaveplan/api-tenant-resolver-header. Every public failure path raises a
{@link HeaderTenantResolverError} carrying one of the namespaced
TENANT_HEADER.* codes so consumers branch on a string value rather than a
brittle instanceof check on a third-party concrete error class.
The registry is the single source of truth for the resolver's wire-level
failure modes. Strict-mode hosts map the codes to HTTP responses (INVALID,
NOT_FOUND_IN_REGISTRY, UNTRUSTED_SOURCE all surface as HTTP 400 unless
the host overrides the mapping); non-strict-mode hosts swallow the codes by
returning null from the resolver so the chain advances.
Features
- Frozen four-entry registry:
INVALID,NOT_FOUND_IN_REGISTRY,UNTRUSTED_SOURCE,INVALID_OPTIONS. - Namespaced
TENANT_HEADER.*codes built viadefineCodesfrom@suaveplan/error. HeaderTenantResolverErrorsubclass narrowscodefor downstream pattern-matching and carries aheaderTenantResolverCodemirror field for ergonomic switch statements.
Usage: Basic
import {
HeaderTenantResolverError,
TENANT_HEADER_CODES,
} from "@suaveplan/api-tenant-resolver-header/error-codes";
throw new HeaderTenantResolverError(
TENANT_HEADER_CODES.INVALID,
"X-Tenant-Id 'Acme!' does not match ^[a-z0-9-]{1,64}$"
);
Usage: Advanced
import {
HeaderTenantResolverError,
TENANT_HEADER_CODES,
} from "@suaveplan/api-tenant-resolver-header/error-codes";
function toHttpStatus(error: HeaderTenantResolverError): number {
switch (error.code) {
case TENANT_HEADER_CODES.INVALID:
case TENANT_HEADER_CODES.NOT_FOUND_IN_REGISTRY:
case TENANT_HEADER_CODES.UNTRUSTED_SOURCE:
return 400;
case TENANT_HEADER_CODES.INVALID_OPTIONS:
return 500;
}
}
API Reference
TENANT_HEADER_CODES— frozen registry with keysINVALID,NOT_FOUND_IN_REGISTRY,UNTRUSTED_SOURCE,INVALID_OPTIONS.type HeaderTenantResolverErrorCode— string union of the four code values, e.g."TENANT_HEADER.INVALID".class HeaderTenantResolverError extends SuaveplanError<HeaderTenantResolverErrorCode>— accepts(code, message, { cause? })and exposesheaderTenantResolverCodealongside the inheritedcodefield.
Implementation Notes
The registry is intentionally minimal — four codes covering the resolver's
four distinct outcomes. Adding a code requires a spec delta because the codes
are part of the package's wire contract. Hosts that need finer-grained
diagnostics attach detail via error.cause; the codes themselves stay coarse
so consumers' switch statements don't proliferate when new validators are
plugged in.
defineCodes freezes the returned object so accidental mutation of the
registry at runtime is impossible — the four TENANT_HEADER.* strings are
the only values that will ever flow through the public surface.