diff --git a/apps/client/src/ee/ai/services/ai-search-service.ts b/apps/client/src/ee/ai/services/ai-search-service.ts index 06c09e8a..0254f5b2 100644 --- a/apps/client/src/ee/ai/services/ai-search-service.ts +++ b/apps/client/src/ee/ai/services/ai-search-service.ts @@ -53,6 +53,9 @@ export async function askAi( try { const parsed = JSON.parse(data); + if (parsed.error) { + throw new Error(parsed.error); + } if (parsed.content) { answer += parsed.content; onChunk?.({ content: parsed.content }); @@ -62,6 +65,9 @@ export async function askAi( onChunk?.({ sources: parsed.sources }); } } catch (e) { + if (e instanceof Error) { + throw e; + } // Skip invalid JSON } } diff --git a/apps/client/src/features/search/components/search-spotlight.tsx b/apps/client/src/features/search/components/search-spotlight.tsx index 2f45b67e..0351c1e2 100644 --- a/apps/client/src/features/search/components/search-spotlight.tsx +++ b/apps/client/src/features/search/components/search-spotlight.tsx @@ -4,6 +4,7 @@ import { Group, Button } from "@mantine/core"; import React, { useState, useMemo, useEffect } from "react"; import { useDebouncedValue } from "@mantine/hooks"; import { useTranslation } from "react-i18next"; +import { notifications } from "@mantine/notifications"; import { searchSpotlightStore } from "../constants.ts"; import { SearchSpotlightFilters } from "./search-spotlight-filters.tsx"; import { useUnifiedSearch } from "../hooks/use-unified-search.ts"; @@ -57,6 +58,8 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) { mutate: triggerAiSearchMutation, //@ts-ignore reset: resetAiMutation, + //@ts-ignore + error: aiSearchError, streamingAnswer, streamingSources, clearStreaming, @@ -68,6 +71,17 @@ export function SearchSpotlight({ spaceId }: SearchSpotlightProps) { resetAiMutation(); }, [query, clearStreaming, resetAiMutation]); + // Show error notification when AI search fails + useEffect(() => { + if (aiSearchError) { + notifications.show({ + message: aiSearchError.message || t("AI search failed. Please try again."), + color: "red", + position: "top-center" + }); + } + }, [aiSearchError, t]); + // Determine result type for rendering const isAttachmentSearch = filters.contentType === "attachment" && (hasLicenseKey || isCloud()); diff --git a/apps/client/src/main.tsx b/apps/client/src/main.tsx index f084b089..63a775de 100644 --- a/apps/client/src/main.tsx +++ b/apps/client/src/main.tsx @@ -51,7 +51,7 @@ root.render( - +