Files
suaveplan/packages/identity/auth/oauth-client/src/errors/oauth-client-error.md
2026-05-27 23:47:53 +01:00

3.6 KiB

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<OAuthClientErrorCode> with name = "OAuthClientError".

Usage: Basic Example

import { OAuthClientError, OAUTH_CLIENT_CODES } from "@suaveplan/oauth-client/errors";

throw new OAuthClientError(
  OAUTH_CLIENT_CODES.INVALID_STATE,
  "oauth.state.mismatch",
);

Usage: Advanced Example

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

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

class OAuthClientError extends SuaveplanError<OAuthClientErrorCode> {
  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.