Skip to content

Commit 10a2ade

Browse files
joyeecheungruyadorno
authored andcommitted
src: improve error message when ICU data cannot be initialized
Previously when we fail to initialize ICU data, the error message is ``` could not initialize ICU (check NODE_ICU_DATA or --icu-data-dir parameters) ``` This patch updates it to something similar to: ``` U_FILE_ACCESS_ERROR: Could not initialize ICU. Check the directory specified by NODE_ICU_DATA or --icu-data-dir contains icudt73l.dat and it's readable ``` Where the expected data file name is the same as U_ICUDATA_NAME. PR-URL: #49666 Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 7c2060c commit 10a2ade

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

src/node.cc

+8-3
Original file line numberDiff line numberDiff line change
@@ -916,9 +916,14 @@ static ExitCode InitializeNodeWithArgsInternal(
916916

917917
// Initialize ICU.
918918
// If icu_data_dir is empty here, it will load the 'minimal' data.
919-
if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir)) {
920-
errors->push_back("could not initialize ICU "
921-
"(check NODE_ICU_DATA or --icu-data-dir parameters)\n");
919+
std::string icu_error;
920+
if (!i18n::InitializeICUDirectory(per_process::cli_options->icu_data_dir,
921+
&icu_error)) {
922+
errors->push_back(icu_error +
923+
": Could not initialize ICU. "
924+
"Check the directory specified by NODE_ICU_DATA or "
925+
"--icu-data-dir contains " U_ICUDATA_NAME ".dat and "
926+
"it's readable\n");
922927
return ExitCode::kInvalidCommandLineArgument;
923928
}
924929
per_process::metadata.versions.InitializeIntlVersions();

src/node_i18n.cc

+14-9
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,21 @@
5454
#include "util-inl.h"
5555
#include "v8.h"
5656

57-
#include <unicode/utypes.h>
5857
#include <unicode/putil.h>
58+
#include <unicode/timezone.h>
5959
#include <unicode/uchar.h>
6060
#include <unicode/uclean.h>
61+
#include <unicode/ucnv.h>
6162
#include <unicode/udata.h>
6263
#include <unicode/uidna.h>
63-
#include <unicode/ucnv.h>
64-
#include <unicode/utf8.h>
65-
#include <unicode/utf16.h>
66-
#include <unicode/timezone.h>
6764
#include <unicode/ulocdata.h>
65+
#include <unicode/urename.h>
66+
#include <unicode/ustring.h>
67+
#include <unicode/utf16.h>
68+
#include <unicode/utf8.h>
69+
#include <unicode/utypes.h>
6870
#include <unicode/uvernum.h>
6971
#include <unicode/uversion.h>
70-
#include <unicode/ustring.h>
7172

7273
#ifdef NODE_HAVE_SMALL_ICU
7374
/* if this is defined, we have a 'secondary' entry point.
@@ -569,8 +570,7 @@ ConverterObject::ConverterObject(
569570
}
570571
}
571572

572-
573-
bool InitializeICUDirectory(const std::string& path) {
573+
bool InitializeICUDirectory(const std::string& path, std::string* error) {
574574
UErrorCode status = U_ZERO_ERROR;
575575
if (path.empty()) {
576576
#ifdef NODE_HAVE_SMALL_ICU
@@ -583,7 +583,12 @@ bool InitializeICUDirectory(const std::string& path) {
583583
u_setDataDirectory(path.c_str());
584584
u_init(&status);
585585
}
586-
return status == U_ZERO_ERROR;
586+
if (status == U_ZERO_ERROR) {
587+
return true;
588+
}
589+
590+
*error = u_errorName(status);
591+
return false;
587592
}
588593

589594
void SetDefaultTimeZone(const char* tzid) {

src/node_i18n.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
namespace node {
3939
namespace i18n {
4040

41-
bool InitializeICUDirectory(const std::string& path);
41+
bool InitializeICUDirectory(const std::string& path, std::string* error);
4242

4343
void SetDefaultTimeZone(const char* tzid);
4444

test/parallel/test-icu-data-dir.js

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
// Flags: --expose-internals
22
'use strict';
33
const common = require('../common');
4+
const { spawnSyncAndExit } = require('../common/child_process');
45
const { internalBinding } = require('internal/test/binding');
5-
const os = require('os');
66

77
const { hasSmallICU } = internalBinding('config');
88
if (!(common.hasIntl && hasSmallICU))
99
common.skip('missing Intl');
1010

11-
const assert = require('assert');
12-
const { spawnSync } = require('child_process');
13-
14-
const expected =
15-
'could not initialize ICU (check NODE_ICU_DATA or ' +
16-
`--icu-data-dir parameters)${os.EOL}`;
17-
1811
{
19-
const child = spawnSync(process.execPath, ['--icu-data-dir=/', '-e', '0']);
20-
assert(child.stderr.toString().includes(expected));
12+
spawnSyncAndExit(
13+
process.execPath,
14+
['--icu-data-dir=/', '-e', '0'],
15+
{
16+
status: 9,
17+
signal: null,
18+
stderr: /Could not initialize ICU/
19+
});
2120
}
2221

2322
{
2423
const env = { ...process.env, NODE_ICU_DATA: '/' };
25-
const child = spawnSync(process.execPath, ['-e', '0'], { env });
26-
assert(child.stderr.toString().includes(expected));
24+
spawnSyncAndExit(
25+
process.execPath,
26+
['-e', '0'],
27+
{ env },
28+
{
29+
status: 9,
30+
signal: null,
31+
stderr: /Could not initialize ICU/
32+
});
2733
}

0 commit comments

Comments
 (0)