Summary
The location check never completes on a self-hosted 2.2.5 instance (Docker image ghcr.io/lissy93/web-check:2.2.5, Node 22.23). Every request ends with the middleware timeout:
Request timed-out after 60000 ms
Cause
api/location.js fetches with mode: 'no-cors':
const getJson = async (url, signal) => {
const r = await fetch(url, { mode: 'no-cors', signal });
https://restcountries.com/v3.1/alpha/<code> now answers 301 Moved Permanently with a Location on another origin (files-03.restcountries.com). In Node's fetch (undici), a no-cors request that meets this cross-origin redirect never settles, and it does not honour its abort signal. enrichCountry() also passes no signal, so the handler waits until the middleware timeout. The geo providers themselves answer in well under a second. The same master code is affected (api/location.js, last changed in 3ba5e58).
Reproduction (inside the 2.2.5 container, Node 22)
const u = 'https://restcountries.com/v3.1/alpha/PL?fields=tld,languages,currencies,area,population';
await fetch(u, { signal: AbortSignal.timeout(15000) }); // 200 in ~0.2 s
await fetch(u, { mode: 'no-cors', signal: AbortSignal.timeout(15000) }); // never settles, abort ignored
Suggested fix
Drop mode: 'no-cors' from getJson. It has no CORS meaning server-side, and all four geo providers returned 200 without it in our test. Optionally also bound the enrichment request:
- const r = await fetch(url, { mode: 'no-cors', signal });
+ const r = await fetch(url, { signal });
`https://restcountries.com/v3.1/alpha/${code}` +
'?fields=tld,languages,currencies,area,population',
+ AbortSignal.timeout(TIMEOUT),
);
With both changes the handler returned full geo data plus country enrichment in about 0.4 s. The unchanged handler still hung after 30 s.
Summary
The
locationcheck never completes on a self-hosted 2.2.5 instance (Docker imageghcr.io/lissy93/web-check:2.2.5, Node 22.23). Every request ends with the middleware timeout:Cause
api/location.jsfetches withmode: 'no-cors':https://restcountries.com/v3.1/alpha/<code>now answers301 Moved Permanentlywith aLocationon another origin (files-03.restcountries.com). In Node's fetch (undici), ano-corsrequest that meets this cross-origin redirect never settles, and it does not honour its abort signal.enrichCountry()also passes no signal, so the handler waits until the middleware timeout. The geo providers themselves answer in well under a second. The samemastercode is affected (api/location.js, last changed in 3ba5e58).Reproduction (inside the 2.2.5 container, Node 22)
Suggested fix
Drop
mode: 'no-cors'fromgetJson. It has no CORS meaning server-side, and all four geo providers returned 200 without it in our test. Optionally also bound the enrichment request:`https://restcountries.com/v3.1/alpha/${code}` + '?fields=tld,languages,currencies,area,population', + AbortSignal.timeout(TIMEOUT), );With both changes the handler returned full geo data plus country enrichment in about 0.4 s. The unchanged handler still hung after 30 s.