first commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
# `error-codes` — `AUTH_JWT_*` stable codes
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Stable error-code registry for `@suaveplan/api-auth-jwt`, exposing the
|
||||
`AUTH_JWT.*` namespace via `defineCodes` from `@suaveplan/error` and a
|
||||
matching `AuthJwtError` subclass of `SuaveplanError`. The registry lists
|
||||
only the codes the package throws — namely the infrastructure failures an
|
||||
operator must act on. Per-request soft failures (bad token, expired
|
||||
signature, wrong audience, etc.) deliberately do not get codes; they
|
||||
collapse to `null` so that the upstream `SessionResolverChain` can move on
|
||||
to the next resolver, which is the documented chain semantic.
|
||||
|
||||
## Features
|
||||
|
||||
- `AUTH_JWT_CODES.JWKS_FETCH_FAILED` — JWKS endpoint unreachable or
|
||||
returned a non-2xx after the configured retries, and there is no cached
|
||||
set old enough to use. Operators see this in logs / metrics; callers
|
||||
see a 401.
|
||||
- `AUTH_JWT_CODES.INVALID_KEY_FORMAT` — `options.staticKey` failed JWK
|
||||
schema validation at construction time.
|
||||
- `AUTH_JWT_CODES.INVALID_CLAIMS_MAPPER` — `options.claimsToPrincipal`
|
||||
threw or returned a value that is not a `Principal` or `null`.
|
||||
- `AuthJwtError` carries the matching `AuthJwtErrorCode`, integrates with
|
||||
the `SuaveplanError` cause-chain, redaction, and OTel span-event
|
||||
adapters from `@suaveplan/error`.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { AUTH_JWT_CODES, AuthJwtError } from "@suaveplan/api-auth-jwt/error-codes";
|
||||
|
||||
try {
|
||||
// ... resolver internals ...
|
||||
} catch (cause) {
|
||||
throw new AuthJwtError(
|
||||
AUTH_JWT_CODES.JWKS_FETCH_FAILED,
|
||||
"JWKS endpoint unreachable",
|
||||
{ cause }
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Branch on the code at the boundary to map infrastructure failures to
|
||||
operator alerts rather than user-facing 401s:
|
||||
|
||||
```ts
|
||||
import { AUTH_JWT_CODES, AuthJwtError } from "@suaveplan/api-auth-jwt/error-codes";
|
||||
|
||||
function isOperatorActionable(err: unknown): err is AuthJwtError {
|
||||
if (!(err instanceof AuthJwtError)) return false;
|
||||
return err.code === AUTH_JWT_CODES.JWKS_FETCH_FAILED;
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `AUTH_JWT_CODES` — frozen record produced by `defineCodes("AUTH_JWT", [...])`.
|
||||
- `AuthJwtErrorCode` — union of the three string literals.
|
||||
- `AuthJwtError extends SuaveplanError<AuthJwtErrorCode>` — `jwtCode`
|
||||
mirrors `code` for ergonomic `instanceof` narrowing.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The three-code registry is intentionally small. Adding "soft" failure
|
||||
codes here would tempt consumers to branch on them, defeating the chain
|
||||
semantic that `null` means "not my caller". If a richer breakdown is
|
||||
needed downstream, emit it on the failure counter (`reason` attribute)
|
||||
rather than as a separate `AUTH_JWT.*` code. Registry membership is the
|
||||
public contract; only add codes through an OpenSpec change.
|
||||
Reference in New Issue
Block a user