UNPKG

graphlit-client

Version:
82 lines (81 loc) 2.81 kB
/** * Internal types used by the streaming implementation * These are not exported to consumers of the library */ /** * Normalized error from an LLM provider. Carries structured metadata * so the retry layer can make decisions without parsing error messages. */ export class ProviderError extends Error { provider; statusCode; retryable; requestId; constructor(message, opts) { super(message, { cause: opts.cause }); this.name = "ProviderError"; this.provider = opts.provider; this.statusCode = opts.statusCode; this.retryable = opts.retryable; this.requestId = opts.requestId; } } /** * Detect common retryable server errors across providers. * Used as a catch-all after provider-specific error classification. */ export function isRetryableServerError(error) { const status = error.status ?? error.statusCode; if (typeof status === "number" && status >= 500) return true; const msg = (error.message || "").toLowerCase(); const type = (error.type || "").toLowerCase(); if (type === "api_error" || type === "server_error") return true; return (msg.includes("internal server error") || msg.includes("service unavailable") || msg.includes("bad gateway") || msg.includes("gateway timeout")); } /** * Detect rate-limit / overloaded errors across providers. */ export function isRateLimitError(error) { const status = error.status ?? error.statusCode; if (status === 429) return true; const type = (error.type || "").toLowerCase(); if (type === "rate_limit_error" || type === "overloaded_error") return true; if (error.code === "rate_limit_exceeded") return true; const msg = (error.message || "").toLowerCase(); return msg.includes("rate limit") || msg.includes("overloaded"); } /** * Detect transient network errors. * * Node's undici (built-in fetch) wraps TCP resets as: * TypeError: terminated * [cause]: Error: read ECONNRESET { code: 'ECONNRESET' } * * The ECONNRESET code lives on the nested `cause`, not the top-level error, * so we check both levels. */ export function isNetworkError(error) { const msg = error.message || ""; const code = error.code || ""; const causeCode = error.cause?.code || ""; return (msg.includes("fetch failed") || msg === "terminated" || code === "ECONNRESET" || code === "ETIMEDOUT" || code === "ECONNREFUSED" || causeCode === "ECONNRESET" || causeCode === "ETIMEDOUT" || causeCode === "ECONNREFUSED"); } /** Extract a request ID from a provider error, if present. */ export function extractRequestId(error) { return error.request_id ?? error.requestId ?? error.headers?.["x-request-id"]; }