Changes in V8/ICU behaviour should be detected&tested&documented|overridden
Version
v14.17.6, v16.14.1, v18.0.0-pre
Platform
Linux nepbook 5.17.0-gentoo-nep #1 SMP Tue Mar 22 08:34:44 +08 2022 i686 Intel(R) Atom(TM) CPU N270 @ 1.60GHz GenuineIntel GNU/Linux
Subsystem
intl, deps
What steps will reproduce the bug?
Example 1
console.log(new Intl.DateTimeFormat('en', { calendar: 'iso8601' }).resolvedOptions().calendar); console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar);
node v14.17.6:
gregory file:///tmp/calendar-14.17.6.mjs:2 console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar); ^ RangeError: Invalid calendars : BAD_BANANA at new DateTimeFormat (<anonymous>) at file:///tmp/calendar-14.17.6.mjs:2:13 at ModuleJob.run (internal/modules/esm/module_job.js:170:25) at async Loader.import (internal/modules/esm/loader.js:178:24) at async Object.loadESM (internal/process/esm_loader.js:68:5)
node v16.14.1:
node v18.0.0-pre:
iso8601 file:///tmp/calendar-18.0.0.mjs:2 console.log(new Intl.DateTimeFormat('en', { calendar: 'BAD_BANANA' }).resolvedOptions().calendar); ^ RangeError: Invalid calendar : BAD_BANANA at new DateTimeFormat (<anonymous>) at file:///tmp/calendar-18.0.0.mjs:2:13 at ModuleJob.run (node:internal/modules/esm/module_job:197:25) at async Promise.all (index 0) at async ESMLoader.import (node:internal/modules/esm/loader:341:24) at async loadESM (node:internal/process/esm_loader:88:5) at async handleMainPromise (node:internal/modules/run_main:61:12)
Example 2
process.env.LANG = 'C'; console.log(new Date().toLocaleString());
node v14.17.6, v16.14.1:
node 18.0.0-pre:
2022-3-23 1:33:56 // LANG="jp" was defined in environment
How often does it reproduce? Is there a required condition?
Depends on Node version; maybe on system-icu, environment, etc.
What is the expected behavior?
Failed tests on deps bump, investigation, decision, solution.
What do you see instead?
Inconsistent behaviour in userland, weird and hard-to-debug bugs.
Additional information
I'm not 100% sure, but example 2 seems to be caused by internal caching in v8/icu. Basically it ignores setted values, such as process.env.{LANG,LC_ALL,LC_TIME}. Similar problem happened with TZ setter earlier; Node overrides it with #20026
No clue about example 1.
Not sure if any of these must be "fixed" in Node itself (i.e. as separate issues/PRs).
Both problems could have been catched by simple tests. Improving coverage would allow to prevent such problems in the future.
Note: if CI runs in some sort of default/canonical environments, it might be a good idea to make it possible to do multiple or random combinations somehow, especially for i18n-related parts.
There is a pretty common tendency between developers to set en_US.UTF-8 locale just to have more searchable and shareable outputs, so some bugs might slip off even from a huge multilingual community.