export type WebSocketRequestErrorDetails = Record; /** Error returned when a WebSocket request does not receive a response in time. */ export class WebSocketRequestTimeoutError extends Error { readonly action: string; readonly kind = "timeout" as const; constructor(action: string) { super(`WebSocket request timed out: ${action}`); this.name = "WebSocketRequestTimeoutError"; this.action = action; } } export function isWebSocketRequestTimeoutError( error: unknown, ): error is WebSocketRequestTimeoutError { return error instanceof WebSocketRequestTimeoutError; } /** Error returned when the backend rejects a request with a typed payload. */ export class WebSocketRequestError extends Error { readonly code?: string; readonly details?: WebSocketRequestErrorDetails; constructor(message: string, code?: string, details?: WebSocketRequestErrorDetails) { super(message); this.name = "WebSocketRequestError"; this.code = code; this.details = details; } } /** Preserve the structured fields from a rejected WebSocket request. */ export function toWebSocketRequestError(payload: unknown): WebSocketRequestError { const record = typeof payload === "object" && payload !== null ? (payload as { code?: unknown; message?: unknown; details?: unknown }) : undefined; // i18n-exempt: transport fallback used when the backend supplies no message. const message = typeof record?.message === "string" && record.message ? record.message : "WebSocket request failed"; const code = typeof record?.code === "string" ? record.code : undefined; const details = typeof record?.details === "object" && record.details !== null ? (record.details as WebSocketRequestErrorDetails) : undefined; return new WebSocketRequestError(message, code, details); }