fix(ui): fix cleanup in useFetchGet hook

Don't try to set the response if request was canceled
This commit is contained in:
Łukasz Mierzwa
2020-05-18 11:03:01 +01:00
committed by Łukasz Mierzwa
parent ba459a08e2
commit 80160baaf7
2 changed files with 96 additions and 17 deletions

View File

@@ -45,27 +45,27 @@ const useFetchGet = (uri, { autorun = true, deps = [] } = {}) => {
FetchRetryConfig
);
let body;
const contentType = res.headers.get("content-type");
if (contentType && contentType.indexOf("application/json") !== -1) {
body = await res.json();
} else {
body = await res.text();
}
if (res.ok) {
setResponse(body);
} else {
setError(body);
}
setIsLoading(false);
setIsRetrying(false);
} catch (error) {
if (!isCanceled.current) {
setError(error.message);
let body;
const contentType = res.headers.get("content-type");
if (contentType && contentType.indexOf("application/json") !== -1) {
body = await res.json();
} else {
body = await res.text();
}
if (res.ok) {
setResponse(body);
} else {
setError(body);
}
setIsLoading(false);
setIsRetrying(false);
}
} catch (error) {
setError(error.message);
setIsLoading(false);
setIsRetrying(false);
}
}, [uri]);

View File

@@ -204,6 +204,32 @@ describe("useFetchGet", () => {
expect(result.current.isRetrying).toBe(false);
});
it("error is updated on uparsable JSON", async () => {
fetchMock.mock("http://localhost/json/invalid", {
headers: { "Content-Type": "application/json" },
body: "this is not a valid JSON body",
});
const { result, waitForNextUpdate } = renderHook(() =>
useFetchGet("http://localhost/json/invalid")
);
expect(result.current.response).toBe(null);
expect(result.current.error).toBe(null);
expect(result.current.isLoading).toBe(true);
expect(result.current.isRetrying).toBe(false);
jest.runOnlyPendingTimers();
await waitForNextUpdate();
expect(result.current.response).toBe(null);
expect(result.current.error).toBe(
"invalid json response body at http://localhost/json/invalid reason: Unexpected token h in JSON at position 1"
);
expect(result.current.isLoading).toBe(false);
expect(result.current.isRetrying).toBe(false);
});
it("doesn't update response on 200 response after cleanup", async () => {
fetchMock.mock("http://localhost/slow/ok", {
delay: 1000,
@@ -288,4 +314,57 @@ describe("useFetchGet", () => {
await fetchMock.flush(true);
}
});
it("doesn't update error on unparsable JSON after cleanup", async () => {
fetchMock.mock("http://localhost/slow/json/invalid", {
delay: 1000,
headers: { "Content-Type": "application/json" },
body: "this is not a valid JSON body",
});
const Component = () => {
const { response, error, isLoading } = useFetchGet(
"http://localhost/slow/json/invalid"
);
return (
<span>
<span>{response}</span>
<span>{error}</span>
<span>{isLoading}</span>
</span>
);
};
const tree = mount(<Component />);
tree.unmount();
jest.runOnlyPendingTimers();
await fetchMock.flush(true);
});
it("doesn't update response after cleanup", async () => {
fetchMock.mock("http://localhost/slow/text", {
delay: 1000,
body: "ok",
});
const Component = () => {
const { response, error, isLoading } = useFetchGet(
"http://localhost/slow/text"
);
return (
<span>
<span>{response}</span>
<span>{error}</span>
<span>{isLoading}</span>
</span>
);
};
const tree = mount(<Component />);
tree.unmount();
jest.runOnlyPendingTimers();
await fetchMock.flush(true);
});
});