diff --git a/stores/__tests__/email-store-plugin-search-results.test.ts b/stores/__tests__/email-store-plugin-search-results.test.ts index c914d1109..5bbd9745e 100644 --- a/stores/__tests__/email-store-plugin-search-results.test.ts +++ b/stores/__tests__/email-store-plugin-search-results.test.ts @@ -150,6 +150,22 @@ describe('onProvideSearchResults', () => { expect(useEmailStore.getState().externalSearchPending).toEqual([]); }); + it('waits no more for the plugins of a search that failed', async () => { + const answer = deferred(); + emailHooks.onProvideSearchResults.register('crm', () => answer.promise); + vi.mocked(client.searchEmails).mockRejectedValueOnce(new Error('boom')); + + await useEmailStore.getState().searchEmails(client, 'resolution'); + expect(useEmailStore.getState().error).toBe('boom'); + expect(useEmailStore.getState().externalSearchPending).toEqual([]); + + answer.resolve([entry('late')]); + await answer.promise; + await new Promise((r) => setTimeout(r, 0)); + expect(useEmailStore.getState().externalSearchResults).toEqual([]); + expect(useEmailStore.getState().externalSearchPending).toEqual([]); + }); + it('waits no more for the plugins of a search that was replaced', async () => { emailHooks.onProvideSearchResults.register('crm', (_results: ExternalSearchResult[], { query }: { query: string }) => (query === 'one' ? new Promise(() => {}) : [entry('two')])); diff --git a/stores/email-store.ts b/stores/email-store.ts index 014731285..30343a07b 100644 --- a/stores/email-store.ts +++ b/stores/email-store.ts @@ -5353,12 +5353,15 @@ export const useEmailStore = create((set, get) => ({ highlightWhenSnippetsArrive('snippets' in result ? result.snippets : undefined); } catch (error) { if (controller.signal.aborted) return; + // Plugins still answering this search have nothing to add to an error. + providedSearchRun = null; set({ error: error instanceof Error ? error.message : "Failed to search emails", searchQuery: typedQuery, isLoading: false, emails: [], externalSearchResults: [], + externalSearchPending: [], hasMoreEmails: false, totalEmails: 0, searchAbortController: null, @@ -5465,11 +5468,14 @@ export const useEmailStore = create((set, get) => ({ highlightWhenSnippetsArrive('snippets' in result ? result.snippets : undefined); } catch (error) { if (controller.signal.aborted) return; + // Plugins still answering this search have nothing to add to an error. + providedSearchRun = null; set({ error: error instanceof Error ? error.message : "Failed to search emails", isLoading: false, emails: [], externalSearchResults: [], + externalSearchPending: [], hasMoreEmails: false, totalEmails: 0, searchAbortController: null,