From e2717ceb1f1be34cb7f6a14bba1e983512d109f8 Mon Sep 17 00:00:00 2001 From: DeskClaw Bot Date: Wed, 22 Apr 2026 04:03:15 +0000 Subject: [PATCH] fix(renderer): avoid non-iterable provider data --- src/lib/host-api.ts | 22 ++++++++++++++++++++-- src/pages/Chat/ChatToolbar.tsx | 4 ++-- src/stores/providers.ts | 6 +++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/lib/host-api.ts b/src/lib/host-api.ts index 1ffd7887e..c8622abe5 100644 --- a/src/lib/host-api.ts +++ b/src/lib/host-api.ts @@ -89,15 +89,33 @@ function parseUnifiedProxyResponse( } const data: HostApiProxyData = response.data ?? {}; + const status = data.status ?? 200; + const ok = typeof data.ok === 'boolean' + ? data.ok + : status >= 200 && status < 300; + trackUiEvent('hostapi.fetch', { path, method, source: 'ipc-proxy', durationMs: Date.now() - startedAt, - status: data.status ?? 200, + status, }); - if (data.status === 204) return undefined as T; + if (!ok) { + const json = data.json; + const message = (json && typeof json === 'object' && 'error' in (json as Record)) + ? String((json as Record).error) + : (typeof json === 'string' && json.trim() ? json : (data.text || `HTTP ${status}`)); + throw normalizeAppError(new Error(message), { + source: 'ipc-proxy', + path, + method, + status, + }); + } + + if (status === 204) return undefined as T; if (data.json !== undefined) return data.json as T; return data.text as T; } diff --git a/src/pages/Chat/ChatToolbar.tsx b/src/pages/Chat/ChatToolbar.tsx index c1a640b25..32418d02d 100644 --- a/src/pages/Chat/ChatToolbar.tsx +++ b/src/pages/Chat/ChatToolbar.tsx @@ -77,13 +77,13 @@ export function ChatToolbar() { const providerVendorById = useMemo(() => { const map = new Map(); - for (const v of providerVendors) map.set(v.id, v); + for (const v of (Array.isArray(providerVendors) ? providerVendors : [])) map.set(v.id, v); return map; }, [providerVendors]); const providerStatusById = useMemo(() => { const map = new Map(); - for (const s of providerStatuses) map.set(s.id, s); + for (const s of (Array.isArray(providerStatuses) ? providerStatuses : [])) map.set(s.id, s); return map; }, [providerStatuses]); diff --git a/src/stores/providers.ts b/src/stores/providers.ts index fb74d4349..67999cfbf 100644 --- a/src/stores/providers.ts +++ b/src/stores/providers.ts @@ -88,9 +88,9 @@ export const useProviderStore = create((set, get) => ({ const snapshot = await fetchProviderSnapshot(); set({ - statuses: snapshot.statuses ?? [], - accounts: snapshot.accounts ?? [], - vendors: snapshot.vendors ?? [], + statuses: Array.isArray(snapshot.statuses) ? snapshot.statuses : [], + accounts: Array.isArray(snapshot.accounts) ? snapshot.accounts : [], + vendors: Array.isArray(snapshot.vendors) ? snapshot.vendors : [], defaultAccountId: snapshot.defaultAccountId ?? null, loading: false });