-
Notifications
You must be signed in to change notification settings - Fork 539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fetch
may try to use a closed connection
#3492
Comments
const {createServer} = require('node:http');
const port = 8080;
const url = 'http://localhost:' + port;
const server = createServer((req, res) => res.end()).listen(port, async () => {
await fetch(url);
server.closeIdleConnections();
setImmediate(async () => {
await fetch(url); // Throws TypeError with cause UND_ERR_SOCKET or ECONNRESET
server.close();
});
});
|
Summary: Pull Request resolved: #1327 Updating `node-fetch` to the latest version caused tests in `packages/metro/src/integration_tests/__tests__/server-test.js` to fail. Running each test case inside the file failed individually, but there seems to have been a race condition between the tests causing subsequent tests to fail with the following error: ``` FetchError: request to http://localhost:10028/import-export/index.bundle?platform=ios&dev=true&minify=false failed, reason: socket hang up ``` It happens because the "connection: close" header is removed in the latest version of `node-fetch`: node-fetch/node-fetch#1765 and can be fixed by adding this header manually to fetches. ``` fetch('path', {headers: {'Connection': 'close'}}); ``` This diff introduces a workaround where we add that header, however `fetch` is expected to work even without it when the following bug is fixed: https://github.com/nodejs/node/issues/54484 Reviewed By: robhogan Differential Revision: D61336391
Summary: Pull Request resolved: #1327 Updating `node-fetch` to the latest version caused tests in `packages/metro/src/integration_tests/__tests__/server-test.js` to fail. Running each test case inside the file failed individually, but there seems to have been a race condition between the tests causing subsequent tests to fail with the following error: ``` FetchError: request to http://localhost:10028/import-export/index.bundle?platform=ios&dev=true&minify=false failed, reason: socket hang up ``` It happens because the "connection: close" header is removed in the latest version of `node-fetch`: node-fetch/node-fetch#1765 and can be fixed by adding this header manually to fetches. ``` fetch('path', {headers: {'Connection': 'close'}}); ``` This diff introduces a workaround where we add that header, however `fetch` is expected to work even without it when the following bug is fixed: https://github.com/nodejs/node/issues/54484 Also, since `node-fetch` was only used in this one test, it was actually a good opportunity to remove it from the project's dependencies altogether. Reviewed By: robhogan Differential Revision: D61336391 fbshipit-source-id: 898c9745dbbc1e622699ff36b4112a95c3c68656
If I put following line in setImmediate then it works as expected, but other tests fail undici/lib/dispatcher/client.js Line 292 in 69cfd97
|
I don't think this is an undici specific issue, as same thing would happen by using native This seems to be an limitation with |
To extend @jazelly's point - here is a small repo with // fetch-test.js
import { createServer, request } from "node:http";
const port = 8084;
const url = new URL("http://localhost:" + port);
const server = createServer((req, res) => res.end()).listen(port, async () => {
function httpRequestPromise(reqOptions) {
return new Promise((resolve, reject) => {
const req = request(reqOptions, (res) => {
console.log(`STATUS: ${res.statusCode}`);
res.setEncoding("utf8");
res.on("data", () => {});
res.on("end", () => {
resolve();
});
});
req.on("error", (error) => {
console.error(`Request error: ${error.message}`);
reject(error);
});
req.end();
});
}
await httpRequestPromise({
headers: {
// 'Content-Type': 'application/json',
Connection: "keep-alive",
},
hostname: url.hostname,
port: url.port,
path: url.pathname,
});
server.closeIdleConnections();
console.log("idle connections should have closed...");
setImmediate(async () => {
await httpRequestPromise({
hostname: url.hostname,
port: url.port,
path: url.pathname,
});
server.close();
});
}); when run this you should see:
or
if we have Details
Close event was emitted after
|
@nodejs/http |
There are is only one thing to do: always retry the request if the other side is closed. This would mean configuring the |
Version
v22.6.0
Platform
Subsystem
http
What steps will reproduce the bug?
How often does it reproduce? Is there a required condition?
Reproduces consistently for me but the error
cause
varies roughly evenly betweenECONNRESET
andUND_ERR_SOCKET
(details below)What is the expected behavior? Why is that the expected behavior?
fetch
creates a new connection if there are none open, and the request succeeds.What do you see instead?
OR
Additional information
This seems to be quite sensitive to timing/the event loop in a way I haven't pinned down.
setImmediate
(orsetTimeout(cb, 0)
) is required to reproduce the issue.setImmediate
before the secondfetch
makes it succeed.{headers:{'Connection': 'close'}}
to the first request succeeds.The text was updated successfully, but these errors were encountered: