Every fetch() I ever wrote is wrong
The default timeout is ∞
There was a problem at work a few months ago; a script created to pull in a bunch of data from an external API was getting stuck. Everything appeared to run fine until the end, the script would report “four plans left…three plans left…two plans left……” and just hang. Minutes pass with no progress. What gives!?
Well, it turns out part of the problem is that the library we’re using to make requests, node-fetch, does not enforce a timeout by default. This quickly became clear after finding an issue requesting a timeout be added to the fetch specification.
Any HTTP request without a timeout might hang your code forever. - Ian Taylor
So yeah, HTTP requests can hang forever and node-fetch will wait. This seems like a pretty terrible default? Why not default to timing out after some finite amount of time?
node-fetch is not unique in waiting forever, consider Python’s
You can tell Requests to stop waiting for a response after a given number of seconds with the timeout parameter. Nearly all production code should use this parameter in nearly all requests. Failure to do so can cause your program to hang indefinitely. -Requests documentation
If “nearly all production code should use this parameter in nearly all requests”, why not make it the default? An issue exists suggesting exactly this, it’s still open but no progress has been made as of 2020. There doesn’t really seem to be any reason not to have a default timeout and one commenter pointed to examples from other languages that do have default timeouts:
- Haskell’s http-client package, 30 seconds.
- Ruby’s standard library, 60 seconds.
- Scala’s http4s library, 60 seconds.
The blocker for
requests seems to be lack of interest. This issue is a bit esoteric, most users may not encounter it for years (if ever). However, when it does occur this bug can be horribly difficult to track down.