nvm icon indicating copy to clipboard operation
nvm copied to clipboard

nvm commands hang instead of reporting an error when curl is not available

Open pgraham opened this issue 3 years ago • 26 comments

Operating system and version:

Ubuntu 20.04

nvm debug output:

# Will provide if necessary but it's not accurate now that I've installed curl

nvm ls output:

# Will provide if necessary. 

How did you install nvm?

install script

What steps did you perform?

Had a working nvm install break after updating from Ubuntu 16.04 to Ubuntu 20.04

What happened?

Any nvm command that made a remote request would hang

What did you expect to happen?

I expected the command to complete successfully or report a reason for an error

Is there anything in any of your profile files that modifies the PATH?

Yes

When updating to Ubuntu 20.04, curl was remove from my system. After this, any nvm commands would hang and output nothing. Re-installing curl resolved the issue but I spent quite a bit of time to figure out that this was the issue. It would be nice if nvm would fail and report if curl is not available.

pgraham avatar Oct 04 '21 17:10 pgraham

I'm confused why it would hang - if curl isn't found, it would error immediately.

Is there a chance wget was hanging?

ljharb avatar Oct 04 '21 18:10 ljharb

So I'm not familiar with nvm's internals and believe you that it should fail, but, what I observed is that nvm ls-remote and nvm install would hang before I (re)installed curl. I did have one invocation of nvm ls-remote produce output when I ^Cd the command.

Installing curl immediately allowed commands to run.

pgraham avatar Oct 04 '21 18:10 pgraham

wget is working in a general sense. Is there a specific command I can try to see if the problem is there?

pgraham avatar Oct 04 '21 18:10 pgraham

Hmm - without uninstalling curl, it'll be tricky.

If the issue was that you had a copy of curl, but that was hanging, I don't think there's anything nvm could possibly do about it.

ljharb avatar Oct 04 '21 18:10 ljharb

@pgraham is this problem still reproducible? If so, maybe a set -x can help we found that where it hangs.

PeterDaveHello avatar Oct 04 '21 18:10 PeterDaveHello

So it looks like it is wget that's hanging (or just taking a really long time). Using set -x I was able to isolate the issue to this command:

wget -q https://nodejs.org/dist/index.tab -O -

If I try and resolve this URL in the browser everything works fine. Using wget directly, I do eventually get a response after about 3 minutes:

wget https://nodejs.org/dist/index.tab
--2021-10-04 19:54:35--  https://nodejs.org/dist/index.tab
Resolving nodejs.org (nodejs.org)... 2606:4700:10::6814:162e, 2606:4700:10::6814:172e, 104.20.23.46, ...
Connecting to nodejs.org (nodejs.org)|2606:4700:10::6814:162e|:443... failed: Connection timed out.
Connecting to nodejs.org (nodejs.org)|2606:4700:10::6814:172e|:443... failed: Connection timed out.
Connecting to nodejs.org (nodejs.org)|104.20.23.46|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/plain]
Saving to: ‘index.tab’

index.tab                         [ <=>                                            ] 129.24K  --.-KB/s    in 0.006s  

2021-10-04 19:58:55 (22.8 MB/s) - ‘index.tab’ saved [132339]

This command is consistently taking 4.5 minutes to complete and if I actually wait this long the nvm ls-remote command will complete after 4.5 minutes as well. So it looks like this is a wget issue and not a problem with nvm.

pgraham avatar Oct 04 '21 20:10 pgraham

Any chance this is related to the DNS problems that are plaguing Facebook today?

ljharb avatar Oct 04 '21 20:10 ljharb

I'll close, since it's not related to nvm, and there's nothing nvm can do if wget (or curl) decides to hang.

ljharb avatar Oct 04 '21 20:10 ljharb

Cool, thanks for the quick replies!

pgraham avatar Oct 05 '21 01:10 pgraham

A command timeout/timelimit can help mitigate this kind of issue, but no guarantee, and maybe not so worth it.

PeterDaveHello avatar Oct 05 '21 05:10 PeterDaveHello

@PeterDaveHello how would that work in posix?

ljharb avatar Oct 05 '21 05:10 ljharb

Sometimes I use the command timelimit to deal with it, but if curl and wget are the only two commends needed timeout control, maybe just use --timeout for wget and --max-time for curl will be good enough, I could send a pull request if this sounds great.

PeterDaveHello avatar Oct 05 '21 07:10 PeterDaveHello

maybe but the implication here is that the wget binary is just broken, or it'd probably have a default timeout.

ljharb avatar Oct 05 '21 07:10 ljharb

Consider the case of wget binary is broken, then an additional timelimit or timeout command will be needed.

PeterDaveHello avatar Oct 05 '21 07:10 PeterDaveHello

I don't think the wget binary is corrupted. It looks like it's trying and failing to connect to nodejs.com using IPv6 before falling back to v4 and succeeding. Is there an option to wget to force v4 only?

Resolving nodejs.org (nodejs.org)... 2606:4700:10::6814:162e, 2606:4700:10::6814:172e, 104.20.23.46, ...
Connecting to nodejs.org (nodejs.org)|2606:4700:10::6814:162e|:443... failed: Connection timed out.
Connecting to nodejs.org (nodejs.org)|2606:4700:10::6814:172e|:443... failed: Connection timed out.
Connecting to nodejs.org (nodejs.org)|104.20.23.46|:443... connected.

pgraham avatar Oct 05 '21 13:10 pgraham

If so, that is indeed a change we can make.

ljharb avatar Oct 05 '21 14:10 ljharb

@ljharb looks like using --timeout for wget and --max-time for curl is the solution?

PeterDaveHello avatar Oct 05 '21 15:10 PeterDaveHello

@PeterDaveHello a timeout option won't help here; the root of the issue is that wget is trying ipv6, and it shouldn't be.

ljharb avatar Oct 05 '21 16:10 ljharb

Oh I misunderstood the last shell output, but from the earlier one, if it's because the IPv6 connection there is too slow, a timeout could be helpful.

@pgraham it'll be hard to determinate it from nvm, wget supports --inet6-only/--inet4-only options, you can also set inet6_only = on/inet4_only = on in your .wgetrc, it could help.

PeterDaveHello avatar Oct 06 '21 08:10 PeterDaveHello

we can make nvm call wget with --inet4-only as long as all the wget versions we might be running support it.

ljharb avatar Oct 06 '21 16:10 ljharb

That'll make IPv6 only environment not working. Unless nvm will test the network first, which will make the logic more complex.

PeterDaveHello avatar Oct 06 '21 16:10 PeterDaveHello

Fair point, but what kind of environment doesn't work on ipv4?

ljharb avatar Oct 06 '21 22:10 ljharb

As IPv4 run out, there are more and more environment doesn't provide IPv4 address, or you have to pay additional fee for it, some of ISP or VPS is already doing it. The problem here is more like a special case of IPv6 connectivity problem, I don't think it's proper to force IPv4 for it, there could also be problem with IPv4 but IPv6 works fine in the same scenario.

PeterDaveHello avatar Oct 07 '21 05:10 PeterDaveHello

Fair enough. What's the default timeout?

ljharb avatar Oct 07 '21 06:10 ljharb

Which timeout do you mean? Connection timeout, or whole process timeout? Also I'm not sure if the default value will be the same for all versions, even for git, there are different default values for different version.

PeterDaveHello avatar Oct 07 '21 07:10 PeterDaveHello

Before we set a timeout, I’d want to know what those existing defaults are, to understand who the behavior would change for.

ljharb avatar Oct 07 '21 16:10 ljharb