# oauth-client-error _(no submodules)_ ## Purpose Defines the stable error-code registry and typed error class for `@suaveplan/oauth-client`. All runtime failures thrown by this package originate from `OAuthClientError`, which extends `SuaveplanError` to provide deterministic error codes, cause-chain traversal, structured context, and OTel span-event integration inherited from `@suaveplan/error`. Having a single error hierarchy makes it straightforward for callers to distinguish OAuth-specific failures (via `instanceof OAuthClientError`) from other application errors and to map codes to user-facing messages without pattern-matching raw strings. ## Features - `OAUTH_CLIENT_CODES` — stable, tree-shakeable code registry produced by `defineCodes("OAUTH_CLIENT", …)`. - Codes for every failure domain: authorization, token exchange, token refresh, token revocation, token expiry, state/PKCE mismatch, OIDC discovery, config validation, ID-token validation, and unknown-provider lookups. - `OAuthClientErrorCode` — union type derived directly from the registry, providing exhaustive narrowing. - `OAuthClientError` — public constructor extending `SuaveplanError` with `name = "OAuthClientError"`. ## Usage: Basic Example ```ts import { OAuthClientError, OAUTH_CLIENT_CODES } from "@suaveplan/oauth-client/errors"; throw new OAuthClientError( OAUTH_CLIENT_CODES.INVALID_STATE, "oauth.state.mismatch", ); ``` ## Usage: Advanced Example ```ts import { OAuthClientError, OAUTH_CLIENT_CODES } from "@suaveplan/oauth-client/errors"; try { const tokens = await client.handleCallback(code, state, storedState, verifier); } catch (err) { if (err instanceof OAuthClientError) { switch (err.code) { case OAUTH_CLIENT_CODES.INVALID_STATE: // CSRF attack or stale session — abort break; case OAUTH_CLIENT_CODES.TOKEN_EXCHANGE_FAILED: // Show user-facing error with err.context?.statusCode break; default: throw err; } } } ``` ## API Reference ### `OAUTH_CLIENT_CODES` ```ts const OAUTH_CLIENT_CODES: { AUTHORIZATION_FAILED: string; TOKEN_EXCHANGE_FAILED: string; TOKEN_REQUEST_FAILED: string; TOKEN_REFRESH_FAILED: string; TOKEN_REVOKE_FAILED: string; TOKEN_EXPIRED: string; INVALID_STATE: string; PKCE_MISMATCH: string; DISCOVERY_FAILED: string; INVALID_CONFIG: string; INVALID_ID_TOKEN: string; UNKNOWN_PROVIDER: string; } ``` Stable code registry. Each value is a namespaced string such as `"OAUTH_CLIENT.INVALID_STATE"`. ### `OAuthClientErrorCode` Union type of all values in `OAUTH_CLIENT_CODES`. Useful for exhaustive `switch` statements. ### `OAuthClientError` ```ts class OAuthClientError extends SuaveplanError { constructor(code: OAuthClientErrorCode, messageKey: string, options?: SuaveplanErrorOptions): void; } ``` - `code` — one of `OAUTH_CLIENT_CODES` values. - `messageKey` — i18n message key (e.g. `"oauth.state.mismatch"`). - `options.cause` — original error to attach as the causal chain. - `options.context` — arbitrary structured metadata surfaced by `@suaveplan/error`. ## Implementation Notes `defineCodes` produces a frozen object whose values are stable across builds and minifiers — no runtime reflection or `Object.keys` enumeration is needed by callers. The `noUselessConstructor` biome lint suppression is intentional: the explicit `public constructor` widens the protected base constructor to public access, which is a meaningful API contract not enforced by inheritance alone.