first commit
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# `error-codes` — stable error-code registry
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Defines the namespaced `TENANT_SUBDOMAIN.*` error-code registry plus the
|
||||
concrete `SubdomainTenantResolverError` class for the
|
||||
`@suaveplan/api-tenant-resolver-subdomain` package. Every public failure
|
||||
path in the resolver constructs an error with one of these codes so
|
||||
consumers can branch on a stable string value (e.g. `error.code ===
|
||||
TENANT_SUBDOMAIN_CODES.BASE_DOMAIN_MISMATCH`) and `instanceof
|
||||
SubdomainTenantResolverError` narrows `code` to the union type.
|
||||
|
||||
These codes back The host-side mapping (4xx vs 5xx response
|
||||
shape) and the OTel `outcome` label so an operator dashboarding tenant
|
||||
resolution sees the exact failure mode without parsing free-text
|
||||
messages.
|
||||
|
||||
## Features
|
||||
|
||||
- Five stable codes: `INVALID`, `NOT_FOUND_IN_REGISTRY`,
|
||||
`BASE_DOMAIN_MISMATCH`, `FORWARDED_HOST_UNTRUSTED`, `INVALID_OPTIONS`.
|
||||
- `defineCodes` from `@suaveplan/error` — values are frozen and the
|
||||
namespace prefix (`TENANT_SUBDOMAIN.`) is applied once.
|
||||
- Subclass with public-constructor lint compliance and a redundant
|
||||
`subdomainTenantResolverCode` field for downstream type narrowing.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
SubdomainTenantResolverError,
|
||||
TENANT_SUBDOMAIN_CODES,
|
||||
} from "@suaveplan/api-tenant-resolver-subdomain/error-codes";
|
||||
|
||||
throw new SubdomainTenantResolverError(
|
||||
TENANT_SUBDOMAIN_CODES.INVALID,
|
||||
"Label 'ACME!' contains forbidden characters"
|
||||
);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import {
|
||||
SubdomainTenantResolverError,
|
||||
TENANT_SUBDOMAIN_CODES,
|
||||
} from "@suaveplan/api-tenant-resolver-subdomain/error-codes";
|
||||
|
||||
try {
|
||||
await resolver.resolve(request);
|
||||
} catch (e) {
|
||||
if (e instanceof SubdomainTenantResolverError) {
|
||||
switch (e.code) {
|
||||
case TENANT_SUBDOMAIN_CODES.BASE_DOMAIN_MISMATCH:
|
||||
return new Response("Wrong domain", { status: 400 });
|
||||
case TENANT_SUBDOMAIN_CODES.FORWARDED_HOST_UNTRUSTED:
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
default:
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `TENANT_SUBDOMAIN_CODES` — frozen record of code constants.
|
||||
- `SubdomainTenantResolverErrorCode` — union of the registered codes.
|
||||
- `SubdomainTenantResolverError` — concrete subclass of
|
||||
`SuaveplanError<SubdomainTenantResolverErrorCode>`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The registry is built with `defineCodes("TENANT_SUBDOMAIN", [...] as const)`
|
||||
so the namespace prefix is enforced once and every value is statically
|
||||
typed as `TENANT_SUBDOMAIN.<NAME>`. The error subclass exposes a public
|
||||
constructor (per the api-stack public-constructor lint rule) and carries
|
||||
a `subdomainTenantResolverCode` field so callers that down-cast on the
|
||||
narrow class don't have to re-narrow the inherited `code` field.
|
||||
Reference in New Issue
Block a user