Skip to content

Commit ebef8fe

Browse files
mxosmanMahmoud
and
Mahmoud
authored
Handle network errors (#661)
* Throw error in the event of a network error * Throw error sent to catch without adding extra copy * Fix tests * Correct snapshot --------- Co-authored-by: Mahmoud <[email protected]>
1 parent fe0a0c7 commit ebef8fe

File tree

4 files changed

+48
-27
lines changed

4 files changed

+48
-27
lines changed

spotlight-client/src/contentModels/Metric.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import fetchMock from "jest-fetch-mock";
2323
import JsZip from "jszip";
2424
import { when } from "mobx";
2525
import { fromPromise } from "mobx-utils";
26-
import allTestContent from "./__fixtures__/tenant_content_exhaustive";
2726
import { MetricTypeId, MetricTypeIdList } from "../contentApi/types";
2827
import { reactImmediately } from "../testUtils";
28+
import allTestContent from "./__fixtures__/tenant_content_exhaustive";
2929
import createMetricMapping from "./createMetricMapping";
3030

3131
jest.mock("downloadjs");
@@ -170,7 +170,7 @@ test("fetch error state", async () => {
170170

171171
reactImmediately(() => {
172172
expect(metric.error?.message).toBe(
173-
"Metrics API responded with status 500. Error message: test error message"
173+
"Error: Metrics API responded with status 500. Error message: test error message"
174174
);
175175
});
176176

spotlight-client/src/contentModels/RacialDisparitiesNarrative.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ test("fetch error state", async () => {
7979
reactImmediately(() => {
8080
expect(narrative.isLoading).toBe(false);
8181
expect(narrative.error?.message).toBe(
82-
"Metrics API responded with status 500. Error message: test error message"
82+
"Error: Metrics API responded with status 500. Error message: test error message"
8383
);
8484
});
8585

spotlight-client/src/metricsApi/fetchMetrics.test.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
// =============================================================================
1717

1818
import fetchMock from "jest-fetch-mock";
19-
import { fetchAndTransformMetric, fetchMetrics } from "./fetchMetrics";
20-
import { waitForTestServer } from "../testUtils";
2119
import { ERROR_MESSAGES } from "../constants";
20+
import { waitForTestServer } from "../testUtils";
21+
import { fetchAndTransformMetric, fetchMetrics } from "./fetchMetrics";
2222

2323
describe("fetchMetrics", () => {
2424
test("returns fetched metrics", async () => {
@@ -138,4 +138,20 @@ describe("fetchAndTransformMetric", () => {
138138
fetchMock.resetMocks();
139139
fetchMock.dontMock();
140140
});
141+
142+
test("handles network errors", async () => {
143+
expect.hasAssertions();
144+
fetchMock.mockReject(new Error("Network error"));
145+
146+
try {
147+
await fetchMetrics({
148+
metricNames: ["any_metric"],
149+
tenantId: "US_ND",
150+
});
151+
} catch (e) {
152+
expect(e.message).toBe(`Error: Network error`);
153+
}
154+
155+
fetchMock.resetMocks();
156+
});
141157
});

spotlight-client/src/metricsApi/fetchMetrics.ts

+27-22
Original file line numberDiff line numberDiff line change
@@ -45,31 +45,36 @@ export async function fetchMetrics({
4545
// we need some way to get the auth token from the userStore, so we pass a reference to the method in this way.
4646
// ideally fetching metrics should be handled in its own mobx store rather than in the content models. See issue #560
4747
const token = await rootStore?.userStore.getToken();
48-
const response = await fetch(
49-
`${process.env.REACT_APP_API_URL}/api/${tenantId}/public`,
50-
{
51-
body: JSON.stringify({
52-
metrics: metricNames,
53-
}),
54-
headers: {
55-
Authorization: `Bearer ${token}`,
56-
"Content-Type": "application/json",
57-
},
58-
method: "POST",
48+
49+
try {
50+
const response = await fetch(
51+
`${process.env.REACT_APP_API_URL}/api/${tenantId}/public`,
52+
{
53+
body: JSON.stringify({
54+
metrics: metricNames,
55+
}),
56+
headers: {
57+
Authorization: `Bearer ${token}`,
58+
"Content-Type": "application/json",
59+
},
60+
method: "POST",
61+
}
62+
);
63+
64+
if (response.ok) {
65+
const responseData: MetricsApiResponse = await response.json();
66+
return responseData;
5967
}
60-
);
6168

62-
if (response.ok) {
63-
const responseData: MetricsApiResponse = await response.json();
64-
return responseData;
69+
const errorResponse: ErrorAPIResponse = await response.json();
70+
throw new Error(
71+
`Metrics API responded with status ${response.status}. Error message: ${
72+
errorResponse.error || "none"
73+
}`
74+
);
75+
} catch (error) {
76+
throw new Error(`${error}`);
6577
}
66-
67-
const errorResponse: ErrorAPIResponse = await response.json();
68-
throw new Error(
69-
`Metrics API responded with status ${response.status}. Error message: ${
70-
errorResponse.error || "none"
71-
}`
72-
);
7378
}
7479

7580
/**

0 commit comments

Comments
 (0)