SPB Git

Repository Public

errors.ts 2.3 KB 71 lines typescript

1import type { Provider } from '@aos/shared';23export interface ProviderErrorInit {4  provider: Provider;5  retryable: boolean;6  status?: number | null;7  code?: string | null;8  requestId?: string | null;9  retryAfterMs?: number | null;10  attempts?: number;11  cause?: unknown;12}1314/**15 * The only error type thrown by the adapters. `message` comes from the vendor's error body or from this16 * package; it never contains request headers or API keys.17 */18export class ProviderError extends Error {19  readonly provider: Provider;20  readonly retryable: boolean;21  readonly status: number | null;22  readonly code: string | null;23  readonly requestId: string | null;24  readonly retryAfterMs: number | null;25  attempts: number;2627  constructor(message: string, init: ProviderErrorInit) {28    super(message, init.cause === undefined ? undefined : { cause: init.cause });29    this.name = 'ProviderError';30    this.provider = init.provider;31    this.retryable = init.retryable;32    this.status = init.status ?? null;33    this.code = init.code ?? null;34    this.requestId = init.requestId ?? null;35    this.retryAfterMs = init.retryAfterMs ?? null;36    this.attempts = init.attempts ?? 1;37  }3839  toJSON(): Record<string, unknown> {40    return {41      name: this.name, message: this.message, provider: this.provider, retryable: this.retryable,42      status: this.status, code: this.code, requestId: this.requestId, attempts: this.attempts,43    };44  }45}4647/** `retry-after-ms` (milliseconds) wins over `retry-after` (seconds or HTTP date). Null when absent/invalid. */48export function parseRetryAfter(headers: unknown, nowMs: number = Date.now()): number | null {49  const get = (name: string): string | null => {50    if (headers && typeof (headers as Headers).get === 'function') return (headers as Headers).get(name);51    if (headers && typeof headers === 'object') {52      const v = (headers as Record<string, unknown>)[name];53      return typeof v === 'string' ? v : null;54    }55    return null;56  };57  const ms = get('retry-after-ms');58  if (ms !== null) {59    const n = Number(ms);60    if (Number.isFinite(n) && n >= 0) return n;61  }62  const s = get('retry-after');63  if (s !== null) {64    const n = Number(s);65    if (Number.isFinite(n) && n >= 0) return n * 1000;66    const date = Date.parse(s);67    if (Number.isFinite(date)) return Math.max(0, date - nowMs);68  }69  return null;70}71
Files main
Menu

Theme