From a3c60d0e37798534eb17b6ef9ea6226aad6bc8fb Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Fri, 24 Oct 2025 00:08:11 +0100 Subject: [PATCH] Fix file picker error handling and reduce API calls - Handle file.status() errors gracefully (warn instead of error) - Make git files optional (empty array if endpoint fails) - Prevent duplicate API calls by tracking last query - Only fetch git files once (check if cached before fetching) - Short-circuit when no search query (just show git files) - Better error messages (warn for git, error for search) --- src/components/file-picker.tsx | 61 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/components/file-picker.tsx b/src/components/file-picker.tsx index 6e78ffc7..21eb0e2e 100644 --- a/src/components/file-picker.tsx +++ b/src/components/file-picker.tsx @@ -30,15 +30,18 @@ const FilePicker: Component = (props) => { try { const gitResponse = await props.instanceClient.file.status() - const gitFiles: FileItem[] = (gitResponse.data || []).map((file: any) => ({ - path: file.path, - added: file.added, - removed: file.removed, - isGitFile: true, - })) - setCachedGitFiles(gitFiles) + if (gitResponse?.data) { + const gitFiles: FileItem[] = gitResponse.data.map((file: any) => ({ + path: file.path, + added: file.added, + removed: file.removed, + isGitFile: true, + })) + setCachedGitFiles(gitFiles) + } } catch (error) { - console.error("Failed to fetch git files:", error) + console.warn("Git files not available:", error) + setCachedGitFiles([]) } } @@ -47,51 +50,51 @@ const FilePicker: Component = (props) => { setLoading(true) try { - const searchFilesPromise = searchQuery - ? props.instanceClient.find.files({ query: { query: searchQuery } }) - : Promise.resolve({ data: [] }) - - const searchResponse = await searchFilesPromise const gitFiles = cachedGitFiles() - const searchFiles: FileItem[] = (searchResponse.data || []) + if (!searchQuery) { + setFiles(gitFiles) + setSelectedIndex(0) + setLoading(false) + return + } + + const searchResponse = await props.instanceClient.find.files({ query: { query: searchQuery } }) + + const searchFiles: FileItem[] = (searchResponse?.data || []) .filter((path: string) => !gitFiles.some((gf) => gf.path === path)) .map((path: string) => ({ path, isGitFile: false, })) - const allFiles = searchQuery - ? [...gitFiles.filter((f) => f.path.toLowerCase().includes(searchQuery.toLowerCase())), ...searchFiles] - : gitFiles + const filteredGitFiles = gitFiles.filter((f) => f.path.toLowerCase().includes(searchQuery.toLowerCase())) + const allFiles = [...filteredGitFiles, ...searchFiles] setFiles(allFiles) setSelectedIndex(0) } catch (error) { - console.error("Failed to fetch files:", error) + console.error("Failed to search files:", error) setFiles([]) } finally { setLoading(false) } } - createEffect(() => { - if (props.open) { - fetchGitFiles() - fetchFiles(props.searchQuery) - } - }) + let lastQuery = "" createEffect(() => { if (props.open) { - fetchFiles(props.searchQuery) + if (cachedGitFiles().length === 0) { + fetchGitFiles() + } + if (props.searchQuery !== lastQuery) { + lastQuery = props.searchQuery + fetchFiles(props.searchQuery) + } } }) - createEffect(() => { - setSelectedIndex(0) - }) - function scrollToSelected() { setTimeout(() => { const selectedElement = containerRef?.querySelector('[data-file-selected="true"]')