mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
fix(ui): check if request was canceled on slow body read
This commit is contained in:
committed by
Łukasz Mierzwa
parent
09972e6c57
commit
506177884d
+19
-17
@@ -4,7 +4,7 @@ import merge from "lodash.merge";
|
||||
|
||||
import { CommonOptions } from "Common/Fetch";
|
||||
|
||||
const useFetchAny = (upstreams) => {
|
||||
const useFetchAny = (upstreams, { fetcher = null } = {}) => {
|
||||
const [index, setIndex] = useState(0);
|
||||
const [response, setResponse] = useState({
|
||||
response: null,
|
||||
@@ -37,7 +37,7 @@ const useFetchAny = (upstreams) => {
|
||||
inProgress: true,
|
||||
});
|
||||
try {
|
||||
const res = await fetch(
|
||||
const res = await (fetcher || fetch)(
|
||||
uri,
|
||||
merge({}, { method: "GET" }, CommonOptions, options)
|
||||
);
|
||||
@@ -51,23 +51,25 @@ const useFetchAny = (upstreams) => {
|
||||
body = await res.text();
|
||||
}
|
||||
|
||||
if (res.ok) {
|
||||
setResponse({
|
||||
response: body,
|
||||
error: null,
|
||||
responseURI: uri,
|
||||
inProgress: false,
|
||||
});
|
||||
} else {
|
||||
if (upstreams.length > index + 1) {
|
||||
setIndex(index + 1);
|
||||
} else {
|
||||
if (!isCancelled) {
|
||||
if (res.ok) {
|
||||
setResponse({
|
||||
response: null,
|
||||
error: body,
|
||||
responseURI: null,
|
||||
response: body,
|
||||
error: null,
|
||||
responseURI: uri,
|
||||
inProgress: false,
|
||||
});
|
||||
} else {
|
||||
if (upstreams.length > index + 1) {
|
||||
setIndex(index + 1);
|
||||
} else {
|
||||
setResponse({
|
||||
response: null,
|
||||
error: body,
|
||||
responseURI: null,
|
||||
inProgress: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -96,7 +98,7 @@ const useFetchAny = (upstreams) => {
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
};
|
||||
}, [upstreams, index, reset]);
|
||||
}, [upstreams, index, reset, fetcher]);
|
||||
|
||||
return { ...response, reset };
|
||||
};
|
||||
|
||||
@@ -323,4 +323,35 @@ describe("useFetchAny", () => {
|
||||
expect(result.current.inProgress).toBe(false);
|
||||
expect(result.current.responseURI).toBe(null);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup on slow body read", async () => {
|
||||
let tree;
|
||||
const fetcher = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
headers: {
|
||||
get: () => "text/plain",
|
||||
},
|
||||
text: async () => {
|
||||
tree.unmount();
|
||||
return "ok";
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
const upstreams = [{ uri: "http://localhost/slow/body", options: {} }];
|
||||
const Component = () => {
|
||||
const { response, error, inProgress } = useFetchAny(upstreams, {
|
||||
fetcher: fetcher,
|
||||
});
|
||||
return (
|
||||
<span>
|
||||
<span>{response}</span>
|
||||
<span>{error}</span>
|
||||
<span>{inProgress}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
tree = mount(<Component />);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,10 @@ import promiseRetry from "promise-retry";
|
||||
|
||||
import { CommonOptions, FetchRetryConfig } from "Common/Fetch";
|
||||
|
||||
const useFetchGet = (uri, { autorun = true, deps = [] } = {}) => {
|
||||
const useFetchGet = (
|
||||
uri,
|
||||
{ autorun = true, deps = [], fetcher = null } = {}
|
||||
) => {
|
||||
const [response, setResponse] = useState(null);
|
||||
const [error, setError] = useState(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -27,7 +30,7 @@ const useFetchGet = (uri, { autorun = true, deps = [] } = {}) => {
|
||||
setError(null);
|
||||
const res = await promiseRetry(
|
||||
(retry, number) =>
|
||||
fetch(
|
||||
(fetcher || fetch)(
|
||||
uri,
|
||||
merge(
|
||||
{},
|
||||
@@ -58,20 +61,22 @@ const useFetchGet = (uri, { autorun = true, deps = [] } = {}) => {
|
||||
body = await res.text();
|
||||
}
|
||||
|
||||
if (res.ok) {
|
||||
setResponse(body);
|
||||
} else {
|
||||
setError(body);
|
||||
if (!isCanceled.current) {
|
||||
if (res.ok) {
|
||||
setResponse(body);
|
||||
} else {
|
||||
setError(body);
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsRetrying(false);
|
||||
}
|
||||
setIsLoading(false);
|
||||
setIsRetrying(false);
|
||||
}
|
||||
} catch (error) {
|
||||
setError(error.message);
|
||||
setIsLoading(false);
|
||||
setIsRetrying(false);
|
||||
}
|
||||
}, [uri]);
|
||||
}, [uri, fetcher]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autorun) get();
|
||||
|
||||
@@ -11,8 +11,6 @@ import { useFetchGet } from "./useFetchGet";
|
||||
|
||||
describe("useFetchGet", () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
fetchMock.mock("http://localhost/ok", {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ status: "ok" }),
|
||||
@@ -23,6 +21,7 @@ describe("useFetchGet", () => {
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
fetchMock.resetHistory();
|
||||
});
|
||||
|
||||
@@ -116,7 +115,7 @@ describe("useFetchGet", () => {
|
||||
expect(result.current.retryCount).toBe(FetchRetryConfig.retries + 1);
|
||||
|
||||
expect(fetchMock.calls()).toHaveLength(FetchRetryConfig.retries + 1);
|
||||
expect(fetchMock.lastCall()[0]).toBe("http://localhost/error");
|
||||
expect(fetchMock.lastUrl()).toBe("http://localhost/error");
|
||||
|
||||
//verify headers for each request
|
||||
for (let i = 0; i <= FetchRetryConfig.retries; i++) {
|
||||
@@ -367,4 +366,39 @@ describe("useFetchGet", () => {
|
||||
jest.runOnlyPendingTimers();
|
||||
await fetchMock.flush(true);
|
||||
});
|
||||
|
||||
it("doesn't update response after cleanup on slow body read", async () => {
|
||||
FetchRetryConfig.retries = 0;
|
||||
|
||||
let tree;
|
||||
const fetcher = jest.fn(() =>
|
||||
Promise.resolve({
|
||||
headers: {
|
||||
get: () => "text/plain",
|
||||
},
|
||||
text: async () => {
|
||||
tree.unmount();
|
||||
return "ok";
|
||||
},
|
||||
})
|
||||
);
|
||||
jest.useRealTimers();
|
||||
|
||||
const Component = () => {
|
||||
const {
|
||||
response,
|
||||
error,
|
||||
isLoading,
|
||||
} = useFetchGet("http://localhost/slow/body", { fetcher: fetcher });
|
||||
return (
|
||||
<span>
|
||||
<span>{response}</span>
|
||||
<span>{error}</span>
|
||||
<span>{isLoading}</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
tree = mount(<Component />);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user