Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Unsettled promise when using HttpsProxyAgent #386

Description

@ebeigarts

When using HttpsProxyAgent some requests get stuck forever waiting for the response (timeout & signal abort doesn't work here).

So I tried to reproduce this in a small script: https://gist.github.com/ebeigarts/5f2ee99f94cab438b4b629a849e928f0

Since this is happening in the main loop the node exists early with the Warning: Detected unsettled top-level await, in real world application I'm running this in a long running background worker process, so it just gets stuck there.

Here is the output (~1 out of 5 runs fails with this error):

env DEBUG="*" node ./proxy_test.mjs
  https-proxy-agent Creating new HttpsProxyAgent instance: 'http://groups-RESIDENTIAL,country-LV:[email protected]:8000/' +0ms
  https-proxy-agent Creating `net.Socket`: { ALPNProtocols: [ 'http/1.1' ], host: 'proxy.apify.com', port: 8000 } +3ms
  https-proxy-agent:parse-proxy-response got proxy server response: 'HTTP/1.1 200 Connection Established' {} +0ms
  https-proxy-agent Upgrading socket connection to TLS +1ms
statusCode: 200
.....Warning: Detected unsettled top-level await at file:///.../proxy_test.mjs:69
  await main()
  ^

It fails both with net.https and also with axios (with axios it fails more frequently, probably due to timing).

Then I tried addding some extra debug listeners in the HttpsProxyAgent to try to figure this out:

for (const eventName of ['close', 'connect', 'connectionAttempt', 'connectionAttemptFailed', 'connectionAttemptTimeout', 'data', 'drain', 'end', 'error', 'lookup', 'ready', 'timeout', 'keylog', 'OCSPResponse', 'secureConnect', 'session']) {
    socket.on(eventName, () => {
        debug(`socket "${eventName}" event`)
    })
}

and

const tlsSocket = tls.connect({
    ...omit(setServernameFromNonIpHost(opts), 'host', 'path', 'port'),
    socket,
});
for (const eventName of ['close', 'connect', 'connectionAttempt', 'connectionAttemptFailed', 'connectionAttemptTimeout', 'data', 'drain', 'end', 'error', 'lookup', 'ready', 'timeout', 'keylog', 'OCSPResponse', 'secureConnect', 'session']) {
    tlsSocket.on(eventName, () => {
        debug(`tls socket "${eventName}" event`)
    })
}
return tlsSocket;

As I understand the proxy socket gets closed and then nothing happens:

time env DEBUG="*" node ./proxy_test.mjs
  https-proxy-agent Creating new HttpsProxyAgent instance: 'http://groups-RESIDENTIAL,country-LV:[email protected]:8000/' +0ms
  https-proxy-agent Creating `net.Socket`: { ALPNProtocols: [ 'http/1.1' ], host: 'proxy.apify.com', port: 8000 } +3ms
  https-proxy-agent socket "lookup" event +55ms
  https-proxy-agent socket "lookup" event +0ms
  https-proxy-agent socket "connectionAttempt" event +0ms
  https-proxy-agent socket "connect" event +120ms
  https-proxy-agent socket "ready" event +0ms
  https-proxy-agent socket "data" event +635ms
  https-proxy-agent:parse-proxy-response got proxy server response: 'HTTP/1.1 200 Connection Established' {} +0ms
  https-proxy-agent Upgrading socket connection to TLS +1ms
  https-proxy-agent tls socket "keylog" event +419ms
  https-proxy-agent tls socket "keylog" event +2ms
  https-proxy-agent tls socket "keylog" event +0ms
  https-proxy-agent tls socket "keylog" event +0ms
  https-proxy-agent tls socket "keylog" event +0ms
  https-proxy-agent tls socket "secureConnect" event +2ms
  https-proxy-agent tls socket "session" event +0ms
  https-proxy-agent tls socket "data" event +431ms
  https-proxy-agent tls socket "data" event +11ms
  https-proxy-agent tls socket "data" event +1ms
statusCode: 200
  https-proxy-agent tls socket "data" event +151ms
.  https-proxy-agent tls socket "data" event +6ms
.  https-proxy-agent tls socket "data" event +148ms
.  https-proxy-agent tls socket "data" event +2ms
.  https-proxy-agent tls socket "data" event +109ms
.  https-proxy-agent tls socket "data" event +32ms
.  https-proxy-agent tls socket "data" event +9ms
.  https-proxy-agent tls socket "data" event +1ms
.  https-proxy-agent tls socket "data" event +1ms
.  https-proxy-agent tls socket "data" event +54ms
.  https-proxy-agent tls socket "data" event +22ms
.  https-proxy-agent tls socket "data" event +2ms
.  https-proxy-agent tls socket "data" event +63ms
.  https-proxy-agent tls socket "data" event +1ms
.  https-proxy-agent tls socket "data" event +8ms
.  https-proxy-agent tls socket "data" event +2ms
.  https-proxy-agent tls socket "data" event +1ms
.  https-proxy-agent tls socket "data" event +41ms
.  https-proxy-agent tls socket "data" event +1ms
.  https-proxy-agent tls socket "end" event +1ms
  https-proxy-agent socket "close" event +1ms
  https-proxy-agent tls socket "close" event +0ms
Warning: Detected unsettled top-level await at file:///.../proxy_test.mjs:69
  await main()
  ^




real	0m2.555s
user	0m0.133s
sys	0m0.070s

The only workaround that kind of works is when using keepAlive: true.

Any ideas where the issue is?

Anyway I'm opening this ticket here, so maybe someone has similar issues and they can also use the keepAlive: true workaround.

Maybe HttpsProxyAgent should display some warning if keepAlive is not set to true?

Also maybe keepAlive: true should be the default, maybe also scheduling: 'lifo" ? nodejs/node#37184

Versions:

  • os: mac os 16.6.1 on M3
  • node 22.20.0
  • https-proxy-agent 7.0.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions