Skip to content

Commit

Permalink
fix: show an error when the search connection isn't working
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Apr 18, 2024
1 parent 2cdbcd8 commit 756aaa9
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 12 deletions.
16 changes: 14 additions & 2 deletions src/search-modal/EmptyStates.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// @ts-check
import React from 'react';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
import { Stack } from '@openedx/paragon';
import { Alert, Stack } from '@openedx/paragon';

import { useSearchContext } from './manager/SearchManager';
import EmptySearchImage from './images/empty-search.svg';
Expand All @@ -24,9 +24,21 @@ const InfoMessage = ({ title, subtitle, image }) => (
* @type {React.FC<{children: React.ReactElement}>}
*/
const EmptyStates = ({ children }) => {
const { canClearFilters: hasFiltersApplied, totalHits, searchKeywords } = useSearchContext();
const {
canClearFilters: hasFiltersApplied,
totalHits,
searchKeywords,
hasError,
} = useSearchContext();
const hasQuery = !!searchKeywords;

if (hasError) {
return (
<Alert variant="danger">
<FormattedMessage {...messages.searchError} />
</Alert>
);
}
if (!hasQuery && !hasFiltersApplied) {
// We haven't started the search yet. Display the "start your search" empty state
return (
Expand Down
10 changes: 1 addition & 9 deletions src/search-modal/SearchModal.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,9 @@ describe('<SearchModal />', () => {
expect(await findByText('Start searching to find content')).toBeInTheDocument();
});

it('should render the spinner while the config is loading', () => {
axiosMock.onGet(getContentSearchConfigUrl()).replyOnce(200, new Promise(() => {})); // never resolves
const { getByRole } = render(<RootWrapper />);

const spinner = getByRole('status');
expect(spinner.textContent).toEqual('Loading...');
});

it('should render the error message if the api call throws', async () => {
axiosMock.onGet(getContentSearchConfigUrl()).networkError();
const { findByText } = render(<RootWrapper />);
expect(await findByText('Network Error')).toBeInTheDocument();
expect(await findByText('An error occurred. Unable to load search results.')).toBeInTheDocument();
});
});
1 change: 1 addition & 0 deletions src/search-modal/data/apiHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const useContentSearchResults = ({
blockTypes: pages?.[0]?.blockTypes ?? {},
status: query.status,
isFetching: query.isFetching,
isError: query.isError,
isFetchingNextPage: query.isFetchingNextPage,
// Call this to load more pages. We include some "safety" features recommended by the docs: this should never be
// called while already fetching a page, and parameters (like 'event') should not be passed into fetchNextPage().
Expand Down
4 changes: 3 additions & 1 deletion src/search-modal/manager/SearchManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { useContentSearchConnection, useContentSearchResults } from '../data/api
* isFetchingNextPage: boolean,
* fetchNextPage: () => void,
* closeSearchModal: () => void,
* hasError: boolean,
* }>}
*/
const SearchContext = /** @type {any} */(React.createContext(undefined));
Expand All @@ -55,7 +56,7 @@ export const SearchContextProvider = ({ extraFilter, children, closeSearchModal
}, []);

// Initialize a connection to Meilisearch:
const { data: connectionDetails } = useContentSearchConnection();
const { data: connectionDetails, isError: hasConnectionError } = useContentSearchConnection();
const indexName = connectionDetails?.indexName;
const client = React.useMemo(() => {
if (connectionDetails?.apiKey === undefined || connectionDetails?.url === undefined) {
Expand Down Expand Up @@ -88,6 +89,7 @@ export const SearchContextProvider = ({ extraFilter, children, closeSearchModal
canClearFilters,
clearFilters,
closeSearchModal: closeSearchModal ?? (() => {}),
hasError: hasConnectionError || result.isError,
...result,
},
}, children);
Expand Down
5 changes: 5 additions & 0 deletions src/search-modal/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ const messages = defineMessages({
defaultMessage: 'Open in new window',
description: 'Alt text for the button that opens the search result in a new window',
},
searchError: {
id: 'course-authoring.course-search.searchError',
defaultMessage: 'An error occurred. Unable to load search results.',
description: 'Error message shown when search is not working.',
},
});

export default messages;

0 comments on commit 756aaa9

Please sign in to comment.