From 238ca23d5b3af7f0f0a88179c41837ba9dd8abec Mon Sep 17 00:00:00 2001 From: Daniel Arroyo Date: Mon, 6 Jul 2026 08:51:59 -0400 Subject: [PATCH] fix: null guard on API array responses to prevent crash --- web/src/api.ts | 7 +++++-- web/src/components/FileBrowserModal.tsx | 17 +++++++++-------- web/src/pages/Files.tsx | 25 +++++++++++++------------ 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/web/src/api.ts b/web/src/api.ts index 1f86a73..5660834 100644 --- a/web/src/api.ts +++ b/web/src/api.ts @@ -146,9 +146,12 @@ async function request(method: string, path: string, body?: unknown): Promise return undefined as T; } const text = await res.text(); - const data = text ? JSON.parse(text) : {}; + if (!text) { + throw new ApiError(res.status, "empty response"); + } + const data = JSON.parse(text); if (!res.ok) { - throw new ApiError(res.status, data.error || res.statusText); + throw new ApiError(res.status, (data && data.error) || res.statusText); } return data as T; } diff --git a/web/src/components/FileBrowserModal.tsx b/web/src/components/FileBrowserModal.tsx index ed3afe1..1b9771d 100644 --- a/web/src/components/FileBrowserModal.tsx +++ b/web/src/components/FileBrowserModal.tsx @@ -47,9 +47,9 @@ export default function FileBrowserModal({ initialPath, onSelect, onClose }: Pro useEffect(() => { api.fileCapabilities().then(setCapabilities).catch(() => {}); api.fileRoots().then(r => { - setRoots(r.roots); - if (!initialPath && r.roots.length > 0) { - setCurrentPath(r.roots[0]); + setRoots(r.roots ?? []); + if (!initialPath && (r.roots ?? []).length > 0) { + setCurrentPath(r.roots![0]); } }).catch(() => {}); }, []); @@ -63,10 +63,11 @@ export default function FileBrowserModal({ initialPath, onSelect, onClose }: Pro setError(null); try { const res = await api.listFiles(path, pageNum, LIMIT); + const entries = res.entries ?? []; if (pageNum === 1) { - setEntries(res.entries); + setEntries(entries); } else { - setEntries(prev => [...prev, ...res.entries]); + setEntries(prev => [...prev, ...entries]); } setPage(pageNum); setHasMore(res.has_more); @@ -165,7 +166,7 @@ export default function FileBrowserModal({ initialPath, onSelect, onClose }: Pro )}
- {roots.length > 1 && ( + {(roots ?? []).length > 1 && ( - {searchResults.length > 0 && ( -
-
Resultados ({searchResults.length})
+ {(searchResults ?? []).length > 0 && ( +
+
Resultados ({(searchResults ?? []).length})
{searchResults.map((hit, i) => (
))} - {entries.length === 0 && !loading && ( + {(entries ?? []).length === 0 && !loading && ( {searchQuery ? "Sin resultados" : "Directorio vacío"} @@ -496,7 +497,7 @@ export default function Files() { {hasMore && ( )}