From f3aff1f090dd4af6877165f87b61b1faee2b203f Mon Sep 17 00:00:00 2001 From: phact Date: Mon, 1 Dec 2025 22:42:46 -0500 Subject: [PATCH] bubble up search errors to ui --- frontend/app/api/queries/useGetSearchQuery.ts | 10 ++++++++- frontend/app/knowledge/page.tsx | 21 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/frontend/app/api/queries/useGetSearchQuery.ts b/frontend/app/api/queries/useGetSearchQuery.ts index 1f2cceb2..972f8f16 100644 --- a/frontend/app/api/queries/useGetSearchQuery.ts +++ b/frontend/app/api/queries/useGetSearchQuery.ts @@ -127,6 +127,12 @@ export const useGetSearchQuery = ( }, body: JSON.stringify(searchPayload), }); + + if (!response.ok) { + const errorData = await response.json().catch(() => ({ error: "Unknown error" })); + throw new Error(errorData.error || `Search failed with status ${response.status}`); + } + const data = await response.json(); // Group chunks by filename to create file results similar to page.tsx const fileMap = new Map< @@ -198,7 +204,8 @@ export const useGetSearchQuery = ( return files; } catch (error) { console.error("Error getting files", error); - return []; + // Re-throw the error so React Query can handle it and trigger onError callbacks + throw error; } } @@ -207,6 +214,7 @@ export const useGetSearchQuery = ( queryKey: ["search", queryData, query], placeholderData: (prev) => prev, queryFn: getFiles, + retry: false, // Don't retry on errors - show them immediately ...options, }, queryClient, diff --git a/frontend/app/knowledge/page.tsx b/frontend/app/knowledge/page.tsx index 9a526159..4a26b38f 100644 --- a/frontend/app/knowledge/page.tsx +++ b/frontend/app/knowledge/page.tsx @@ -75,6 +75,7 @@ function SearchPage() { const { parsedFilterData, queryOverride } = useKnowledgeFilter(); const [selectedRows, setSelectedRows] = useState([]); const [showBulkDeleteDialog, setShowBulkDeleteDialog] = useState(false); + const lastErrorRef = useRef(null); const deleteDocumentMutation = useDeleteDocument(); @@ -82,10 +83,28 @@ function SearchPage() { refreshTasks(); }, [refreshTasks]); - const { data: searchData = [], isFetching } = useGetSearchQuery( + const { data: searchData = [], isFetching, error, isError } = useGetSearchQuery( queryOverride, parsedFilterData, ); + + // Show toast notification for search errors + useEffect(() => { + if (isError && error) { + const errorMessage = error instanceof Error ? error.message : "Search failed"; + // Avoid showing duplicate toasts for the same error + if (lastErrorRef.current !== errorMessage) { + lastErrorRef.current = errorMessage; + toast.error("Search error", { + description: errorMessage, + duration: 5000, + }); + } + } else if (!isError) { + // Reset when query succeeds + lastErrorRef.current = null; + } + }, [isError, error]); // Convert TaskFiles to File format and merge with backend results const taskFilesAsFiles: File[] = taskFiles.map((taskFile) => { return {