Skip to content

Commit 5523bf7

Browse files
committed
PR Feedback: Added error handling
1 parent 8142965 commit 5523bf7

File tree

9 files changed

+136
-77
lines changed

9 files changed

+136
-77
lines changed

src/app-search/AppSearchDriver.js

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const DEFAULT_STATE = {
2424
// used to produce the current query results. It is always in sync
2525
// with the Results State
2626
current: 1,
27+
error: "",
2728
filters: [],
2829
resultsPerPage: 0,
2930
searchTerm: "",
@@ -134,31 +135,39 @@ export default class AppSearchDriver {
134135
};
135136
}
136137

137-
return this.client.search(searchTerm, searchOptions).then(resultList => {
138-
this._setState({
139-
current: resultList.info.meta.page.current,
140-
facets: resultList.info.facets,
141-
filters: filters,
142-
requestId: resultList.info.meta.request_id,
143-
results: resultList.results,
144-
resultsPerPage: resultsPerPage,
145-
searchTerm: searchTerm,
146-
sortDirection: sortDirection,
147-
sortField: sortField,
148-
totalResults: resultList.info.meta.page.total_results
149-
});
138+
return this.client.search(searchTerm, searchOptions).then(
139+
resultList => {
140+
this._setState({
141+
current: resultList.info.meta.page.current,
142+
error: "",
143+
facets: resultList.info.facets,
144+
filters: filters,
145+
requestId: resultList.info.meta.request_id,
146+
results: resultList.results,
147+
resultsPerPage: resultsPerPage,
148+
searchTerm: searchTerm,
149+
sortDirection: sortDirection,
150+
sortField: sortField,
151+
totalResults: resultList.info.meta.page.total_results
152+
});
150153

151-
if (!skipPushToUrl) {
152-
this.URLManager.pushStateToURL({
153-
current,
154-
filters,
155-
resultsPerPage,
156-
searchTerm,
157-
sortDirection,
158-
sortField
154+
if (!skipPushToUrl) {
155+
this.URLManager.pushStateToURL({
156+
current,
157+
filters,
158+
resultsPerPage,
159+
searchTerm,
160+
sortDirection,
161+
sortField
162+
});
163+
}
164+
},
165+
error => {
166+
this._setState({
167+
error: `An unexpected error occurred: ${error.message}`
159168
});
160169
}
161-
});
170+
);
162171
};
163172

164173
_setState(newState) {
@@ -177,11 +186,28 @@ export default class AppSearchDriver {
177186
this.subscriptions.push(onStateChange);
178187
}
179188

189+
/**
190+
* Retrieves all available acitons
191+
*
192+
* @returns Object All actions
193+
*/
194+
getActions() {
195+
return {
196+
addFilter: this.addFilter,
197+
removeFilter: this.removeFilter,
198+
setResultsPerPage: this.setResultsPerPage,
199+
setSearchTerm: this.setSearchTerm,
200+
setSort: this.setSort,
201+
setCurrent: this.setCurrent,
202+
trackClickThrough: this.trackClickThrough
203+
};
204+
}
205+
180206
/**
181207
* Retrieve current state. Typically used on app initialization. Subsequent
182208
* state updates should come through subscription.
183209
*
184-
* @returns Current state
210+
* @returns Object Current state
185211
*/
186212
getState() {
187213
// We return a copy of state here, because we want to ensure the state

src/app-search/AppSearchProvider.js

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,40 +30,10 @@ class AppSearchProvider extends Component {
3030

3131
render() {
3232
const { children, driver } = this.props;
33-
const {
34-
current,
35-
facets,
36-
filters,
37-
requestId,
38-
results,
39-
resultsPerPage,
40-
searchTerm,
41-
sortDirection,
42-
sortField,
43-
totalResults
44-
} = this.state;
4533

4634
const providerValue = {
47-
// Search Parameters
48-
current,
49-
filters,
50-
resultsPerPage,
51-
searchTerm,
52-
sortDirection,
53-
sortField,
54-
// Result State
55-
facets,
56-
requestId,
57-
results,
58-
totalResults,
59-
// Actions
60-
addFilter: driver.addFilter,
61-
trackClickThrough: driver.trackClickThrough,
62-
removeFilter: driver.removeFilter,
63-
setCurrent: driver.setCurrent,
64-
setResultsPerPage: driver.setResultsPerPage,
65-
setSearchTerm: driver.setSearchTerm,
66-
setSort: driver.setSort
35+
...this.state,
36+
...driver.getActions()
6737
};
6838

6939
return (

src/components/Body.js

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22

33
import Facets from "../containers/Facets";
44
import PagingInfo from "../containers/PagingInfo";
5+
import ErrorBoundary from "../containers/ErrorBoundary";
56
import Paging from "../containers/Paging";
67
import Results from "../containers/Results";
78
import ResultsPerPage from "../containers/ResultsPerPage";
@@ -11,27 +12,31 @@ import { buildSortOptionsFromConfig } from "../config/config-helper";
1112
export default function Body() {
1213
return (
1314
<div className="reference-ui-body">
14-
<div className="initial-state-message">Type a search above to begin.</div>
15-
<div className="search-results">
16-
<div className="sidebar">
17-
<Sorting sortOptions={buildSortOptionsFromConfig()} />
18-
<Facets />
15+
<ErrorBoundary>
16+
<div className="initial-state-message">
17+
Type a search above to begin.
1918
</div>
20-
<div className="results">
21-
<div className="results__header">
22-
<div className="meta">
23-
<PagingInfo />
24-
<ResultsPerPage />
25-
</div>
26-
</div>
27-
<div className="results__body">
28-
<Results />
19+
<div className="search-results">
20+
<div className="sidebar">
21+
<Sorting sortOptions={buildSortOptionsFromConfig()} />
22+
<Facets />
2923
</div>
30-
<div className="results__footer">
31-
<Paging />
24+
<div className="results">
25+
<div className="results__header">
26+
<div className="meta">
27+
<PagingInfo />
28+
<ResultsPerPage />
29+
</div>
30+
</div>
31+
<div className="results__body">
32+
<Results />
33+
</div>
34+
<div className="results__footer">
35+
<Paging />
36+
</div>
3237
</div>
3338
</div>
34-
</div>
39+
</ErrorBoundary>
3540
</div>
3641
);
3742
}

src/components/ErrorBoundary.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import PropTypes from "prop-types";
2+
import React from "react";
3+
4+
function ErrorBoundary({ children, error }) {
5+
if (error) {
6+
return <div className="search-error">{error}</div>;
7+
}
8+
9+
return children;
10+
}
11+
12+
ErrorBoundary.propTypes = {
13+
children: PropTypes.oneOfType([
14+
PropTypes.arrayOf(PropTypes.element),
15+
PropTypes.element
16+
]).isRequired,
17+
error: PropTypes.string.isRequired
18+
};
19+
20+
export default ErrorBoundary;

src/components/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { default as Body } from "./Body";
2+
export { default as ErrorBoundary } from "./ErrorBoundary";
23
export { default as Facet } from "./Facet";
34
export { default as Facets } from "./Facets";
45
export { default as Header } from "./Header";

src/containers/ErrorBoundary.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import PropTypes from "prop-types";
2+
import React, { Component } from "react";
3+
4+
import withAppSearch from "../app-search/withAppSearch";
5+
import { ErrorBoundary } from "../components";
6+
7+
class ErrorBoundaryContainer extends Component {
8+
static propTypes = {
9+
children: PropTypes.oneOfType([
10+
PropTypes.arrayOf(PropTypes.element),
11+
PropTypes.element
12+
]).isRequired,
13+
error: PropTypes.string.isRequired
14+
};
15+
16+
render() {
17+
return <ErrorBoundary {...this.props} />;
18+
}
19+
}
20+
21+
export default withAppSearch(ErrorBoundaryContainer);

src/containers/Results.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ function formatResultFields(result) {
2727
}
2828
class ResultsContainer extends Component {
2929
static propTypes = {
30+
error: PropTypes.string.isRequired,
3031
results: PropTypes.arrayOf(PropTypes.object).isRequired,
3132
trackClickThrough: PropTypes.func.isRequired
3233
};
@@ -37,7 +38,10 @@ class ResultsContainer extends Component {
3738
};
3839

3940
render() {
40-
const { results } = this.props;
41+
const { error, results } = this.props;
42+
if (error) {
43+
return <div>{error}</div>;
44+
}
4145

4246
return (
4347
<Results>

src/styles/styles.css

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,15 +345,20 @@ a {
345345
font-weight: 400;
346346
text-align: center; }
347347

348-
.initial-state-message {
348+
.initial-state-message,
349+
.search-error {
349350
margin: auto;
350351
display: flex;
351352
justify-content: center;
352353
align-items: center;
353354
height: calc(100vh - 180px);
354355
color: #888888; }
355-
.active-search .initial-state-message {
356-
display: none; }
356+
357+
.active-search .initial-state-message {
358+
display: none; }
359+
360+
.search-error {
361+
color: red; }
357362

358363
.searchbox {
359364
max-width: 1300px;

src/styles/styles.scss

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,26 @@ a {
119119
}
120120
}
121121

122-
.initial-state-message {
122+
.initial-state-message,
123+
.search-error {
123124
margin: auto;
124125
display: flex;
125126
justify-content: center;
126127
align-items: center;
127128
height: calc(100vh - 180px);
128129
color: $helpTextGrayColor;
130+
}
129131

132+
.initial-state-message {
130133
.active-search & {
131134
display: none;
132135
}
133136
}
134137

138+
.search-error {
139+
color: red;
140+
}
141+
135142
.searchbox {
136143
@include limitWidth;
137144
display: flex;

0 commit comments

Comments
 (0)