Skip to content
This repository was archived by the owner on Jun 11, 2021. It is now read-only.

Commit 750c4b5

Browse files
feat(docsearch): catch retry errors in the search client
1 parent 9c330f5 commit 750c4b5

3 files changed

Lines changed: 92 additions & 76 deletions

File tree

packages/docsearch-react/src/DocSearch.tsx

Lines changed: 82 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function DocSearch({
103103
onStateChange({ state }) {
104104
setState(state as any);
105105
},
106-
getSources({ query, state, setContext }) {
106+
getSources({ query, state, setContext, setStatus }) {
107107
return getAlgoliaHits({
108108
searchClient,
109109
queries: [
@@ -141,42 +141,70 @@ export function DocSearch({
141141
},
142142
},
143143
],
144-
}).then((hits: DocSearchHit[]) => {
145-
const formattedHits = hits.map(hit => {
146-
const url = new URL(hit.url);
147-
return {
148-
...hit,
149-
url: hit.url
150-
// @TODO: temporary convenience for development.
151-
.replace(url.origin, '')
152-
.replace('#__docusaurus', ''),
153-
};
154-
});
155-
const sources = groupBy(formattedHits, hit => hit.hierarchy.lvl0);
144+
})
145+
.catch(error => {
146+
// The Algolia `RetryError` happens when all the servers have
147+
// failed, meaning that there's no chance the response comes
148+
// back. This is the right time to display an error.
149+
// See https://github.com/algolia/algoliasearch-client-javascript/blob/2ffddf59bc765cd1b664ee0346b28f00229d6e12/packages/transporter/src/errors/createRetryError.ts#L5
150+
if (error.name === 'RetryError') {
151+
setStatus('error');
152+
}
156153

157-
// We store the `lvl0`s to display them as search suggestions
158-
// in the “no results“ screen.
159-
if (state.context.searchSuggestions === undefined) {
160-
setContext({
161-
searchSuggestions: Object.keys(sources),
154+
throw error;
155+
})
156+
.then((hits: DocSearchHit[]) => {
157+
const formattedHits = hits.map(hit => {
158+
const url = new URL(hit.url);
159+
return {
160+
...hit,
161+
url: hit.url
162+
// @TODO: temporary convenience for development.
163+
.replace(url.origin, '')
164+
.replace('#__docusaurus', ''),
165+
};
162166
});
163-
}
167+
const sources = groupBy(formattedHits, hit => hit.hierarchy.lvl0);
164168

165-
if (!query) {
166-
return [
167-
{
168-
onSelect({ suggestion }) {
169-
saveRecentSearch(suggestion);
170-
onClose();
171-
},
172-
getSuggestionUrl({ suggestion }) {
173-
return suggestion.url;
169+
// We store the `lvl0`s to display them as search suggestions
170+
// in the “no results“ screen.
171+
if (state.context.searchSuggestions === undefined) {
172+
setContext({
173+
searchSuggestions: Object.keys(sources),
174+
});
175+
}
176+
177+
if (!query) {
178+
return [
179+
{
180+
onSelect({ suggestion }) {
181+
saveRecentSearch(suggestion);
182+
onClose();
183+
},
184+
getSuggestionUrl({ suggestion }) {
185+
return suggestion.url;
186+
},
187+
getSuggestions() {
188+
return recentSearches.getAll();
189+
},
174190
},
175-
getSuggestions() {
176-
return recentSearches.getAll();
191+
{
192+
onSelect({ suggestion }) {
193+
saveRecentSearch(suggestion);
194+
onClose();
195+
},
196+
getSuggestionUrl({ suggestion }) {
197+
return suggestion.url;
198+
},
199+
getSuggestions() {
200+
return favoriteSearches.getAll();
201+
},
177202
},
178-
},
179-
{
203+
];
204+
}
205+
206+
return Object.values<DocSearchHit[]>(sources).map(items => {
207+
return {
180208
onSelect({ suggestion }) {
181209
saveRecentSearch(suggestion);
182210
onClose();
@@ -185,46 +213,30 @@ export function DocSearch({
185213
return suggestion.url;
186214
},
187215
getSuggestions() {
188-
return favoriteSearches.getAll();
189-
},
190-
},
191-
];
192-
}
193-
194-
return Object.values<DocSearchHit[]>(sources).map(items => {
195-
return {
196-
onSelect({ suggestion }) {
197-
saveRecentSearch(suggestion);
198-
onClose();
199-
},
200-
getSuggestionUrl({ suggestion }) {
201-
return suggestion.url;
202-
},
203-
getSuggestions() {
204-
return Object.values(
205-
groupBy(items, item => item.hierarchy.lvl1)
206-
)
207-
.map(hits =>
208-
hits.map(item => {
209-
return {
210-
...item,
211-
// eslint-disable-next-line @typescript-eslint/camelcase
212-
__docsearch_parent:
213-
item.type !== 'lvl1' &&
214-
hits.find(
215-
siblingItem =>
216-
siblingItem.type === 'lvl1' &&
217-
siblingItem.hierarchy.lvl1 ===
218-
item.hierarchy.lvl1
219-
),
220-
};
221-
})
216+
return Object.values(
217+
groupBy(items, item => item.hierarchy.lvl1)
222218
)
223-
.flat();
224-
},
225-
};
219+
.map(hits =>
220+
hits.map(item => {
221+
return {
222+
...item,
223+
// eslint-disable-next-line @typescript-eslint/camelcase
224+
__docsearch_parent:
225+
item.type !== 'lvl1' &&
226+
hits.find(
227+
siblingItem =>
228+
siblingItem.type === 'lvl1' &&
229+
siblingItem.hierarchy.lvl1 ===
230+
item.hierarchy.lvl1
231+
),
232+
};
233+
})
234+
)
235+
.flat();
236+
},
237+
};
238+
});
226239
});
227-
});
228240
},
229241
}),
230242
[

packages/docsearch-react/src/ErrorScreen.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import React from 'react';
22

33
export function ErrorScreen() {
44
return (
5-
<p>
6-
We‘re unable to fetch results. You might want to check your network
7-
connection.
8-
</p>
5+
<div className="DocSearch-ErrorScreen">
6+
<p>
7+
We‘re unable to fetch results. You might want to check your network
8+
connection.
9+
</p>
10+
</div>
911
);
1012
}

packages/docsearch-react/src/style.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,9 +525,11 @@ html[data-theme='dark'] {
525525
color: var(--docsearch-muted-color);
526526
}
527527

528-
/* No Results - Empty Screen */
528+
/* No Results - Start Screen - Error Screen */
529529

530-
.DocSearch-NoResults, .DocSearch-EmptyScreen {
530+
.DocSearch-NoResults,
531+
.DocSearch-StartScreen,
532+
.DocSearch-ErrorScreen {
531533
width: 80%;
532534
margin: 0 auto;
533535
text-align: center;

0 commit comments

Comments
 (0)