From 5c624cda4f29aa490e096eb5f9b207a049f40aaf Mon Sep 17 00:00:00 2001 From: bkellam Date: Thu, 20 Nov 2025 16:47:54 -0800 Subject: [PATCH] wip on better error handling --- packages/web/src/actions.ts | 4 ++ .../components/searchBar/searchBar.tsx | 2 +- .../search/components/searchResultsPage.tsx | 5 +- .../app/[domain]/search/useStreamedSearch.ts | 14 +++- packages/web/src/features/search/parser.ts | 65 ++++++++++++------- packages/web/src/lib/errorCodes.ts | 1 + 6 files changed, 61 insertions(+), 30 deletions(-) diff --git a/packages/web/src/actions.ts b/packages/web/src/actions.ts index e194f808..cc239fa9 100644 --- a/packages/web/src/actions.ts +++ b/packages/web/src/actions.ts @@ -48,6 +48,10 @@ export const sew = async (fn: () => Promise): Promise => Sentry.captureException(e); logger.error(e); + if (e instanceof ServiceErrorException) { + return e.serviceError; + } + if (e instanceof Error) { return unexpectedError(e.message); } diff --git a/packages/web/src/app/[domain]/components/searchBar/searchBar.tsx b/packages/web/src/app/[domain]/components/searchBar/searchBar.tsx index 154fb7c5..9ec5f664 100644 --- a/packages/web/src/app/[domain]/components/searchBar/searchBar.tsx +++ b/packages/web/src/app/[domain]/components/searchBar/searchBar.tsx @@ -287,7 +287,7 @@ export const SearchBar = ({ indentWithTab={false} autoFocus={autoFocus ?? false} /> -
+
diff --git a/packages/web/src/app/[domain]/search/components/searchResultsPage.tsx b/packages/web/src/app/[domain]/search/components/searchResultsPage.tsx index b3156169..602082c2 100644 --- a/packages/web/src/app/[domain]/search/components/searchResultsPage.tsx +++ b/packages/web/src/app/[domain]/search/components/searchResultsPage.tsx @@ -33,6 +33,7 @@ import { CodePreviewPanel } from "./codePreviewPanel"; import { FilterPanel } from "./filterPanel"; import { useFilteredMatches } from "./filterPanel/useFilterMatches"; import { SearchResultsPanel, SearchResultsPanelHandle } from "./searchResultsPanel"; +import { ServiceErrorException } from "@/lib/serviceError"; interface SearchResultsPageProps { searchQuery: string; @@ -79,7 +80,7 @@ export const SearchResultsPage = ({ useEffect(() => { if (error) { toast({ - description: `❌ Search failed. Reason: ${error.message}`, + description: `❌ Search failed. Reason: ${error instanceof ServiceErrorException ? error.serviceError.message : error.message}`, }); } }, [error, toast]); @@ -184,7 +185,7 @@ export const SearchResultsPage = ({

Failed to search

-

{error.message}

+

{error instanceof ServiceErrorException ? error.serviceError.message : error.message}

) : ( => { - // First parse the query into a Lezer tree. - const tree = parser.parse(query); - // Then transform the tree into the intermediate representation. - return transformTreeToIR({ - tree, - input: query, - isCaseSensitivityEnabled: options.isCaseSensitivityEnabled ?? false, - isRegexEnabled: options.isRegexEnabled ?? false, - onExpandSearchContext: async (contextName: string) => { - const context = await prisma.searchContext.findUnique({ - where: { - name_orgId: { - name: contextName, - orgId: SINGLE_TENANT_ORG_ID, + try { + // First parse the query into a Lezer tree. + const tree = parser.parse(query); + + // Then transform the tree into the intermediate representation. + return transformTreeToIR({ + tree, + input: query, + isCaseSensitivityEnabled: options.isCaseSensitivityEnabled ?? false, + isRegexEnabled: options.isRegexEnabled ?? false, + onExpandSearchContext: async (contextName: string) => { + const context = await prisma.searchContext.findUnique({ + where: { + name_orgId: { + name: contextName, + orgId: SINGLE_TENANT_ORG_ID, + } + }, + include: { + repos: true, } - }, - include: { - repos: true, + }); + + if (!context) { + throw new Error(`Search context "${contextName}" not found`); } + + return context.repos.map((repo) => repo.name); + }, + }); + } catch (error) { + if (error instanceof SyntaxError) { + throw new ServiceErrorException({ + statusCode: StatusCodes.BAD_REQUEST, + errorCode: ErrorCode.FAILED_TO_PARSE_QUERY, + message: `Failed to parse query "${query}" with message: ${error.message}`, }); - - if (!context) { - throw new Error(`Search context "${contextName}" not found`); - } - - return context.repos.map((repo) => repo.name); - }, - }); + } + throw error; + } } /** diff --git a/packages/web/src/lib/errorCodes.ts b/packages/web/src/lib/errorCodes.ts index 5e545200..fc2abbc0 100644 --- a/packages/web/src/lib/errorCodes.ts +++ b/packages/web/src/lib/errorCodes.ts @@ -34,4 +34,5 @@ export enum ErrorCode { API_KEY_NOT_FOUND = 'API_KEY_NOT_FOUND', INVALID_API_KEY = 'INVALID_API_KEY', CHAT_IS_READONLY = 'CHAT_IS_READONLY', + FAILED_TO_PARSE_QUERY = 'FAILED_TO_PARSE_QUERY', }