Skip to content

Commit 20e1af7

Browse files
committed
export error messages from c++ as constants
1 parent 2c8e56f commit 20e1af7

File tree

2 files changed

+51
-16
lines changed

2 files changed

+51
-16
lines changed

lib/internal/modules/helpers.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ const {
1919
} = require('internal/errors').codes;
2020
const { BuiltinModule } = require('internal/bootstrap/realm');
2121

22+
const {
23+
shouldRetryAsESM: contextifyShouldRetryAsESM,
24+
constants: {
25+
syntaxDetectionErrors: {
26+
esmSyntaxErrorMessages,
27+
throwsOnlyInCommonJSErrorMessages,
28+
},
29+
},
30+
} = internalBinding('contextify');
2231
const { validateString } = require('internal/validators');
2332
const fs = require('fs'); // Import all of `fs` so that it can be monkey-patched.
2433
const internalFS = require('internal/fs/utils');
@@ -320,31 +329,22 @@ function normalizeReferrerURL(referrerName) {
320329
}
321330

322331

323-
const esmSyntaxErrorMessages = new SafeSet([
324-
'Cannot use import statement outside a module', // `import` statements
325-
"Unexpected token 'export'", // `export` statements
326-
"Cannot use 'import.meta' outside a module", // `import.meta` references
327-
]);
328-
const throwsOnlyInCommonJSErrorMessages = new SafeSet([
329-
"Identifier 'module' has already been declared",
330-
"Identifier 'exports' has already been declared",
331-
"Identifier 'require' has already been declared",
332-
"Identifier '__filename' has already been declared",
333-
"Identifier '__dirname' has already been declared",
334-
'await is only valid in async functions and the top level bodies of modules', // Top-level `await`
335-
]);
332+
let esmSyntaxErrorMessagesSet; // Declared lazily in shouldRetryAsESM
333+
let throwsOnlyInCommonJSErrorMessagesSet; // Declared lazily in shouldRetryAsESM
336334
/**
337335
* After an attempt to parse a module as CommonJS throws an error, should we try again as ESM?
338336
* @param {string} errorMessage The string message thrown by V8 when attempting to parse as CommonJS
339337
* @param {string} source Module contents
340338
*/
341339
function shouldRetryAsESM(errorMessage, source) {
342-
if (esmSyntaxErrorMessages.has(errorMessage)) {
340+
esmSyntaxErrorMessagesSet ??= new SafeSet(esmSyntaxErrorMessages);
341+
if (esmSyntaxErrorMessagesSet.has(errorMessage)) {
343342
return true;
344343
}
345344

346-
if (throwsOnlyInCommonJSErrorMessages.has(errorMessage)) {
347-
return /** @type {boolean} */(internalBinding('contextify').shouldRetryAsESM(source));
345+
throwsOnlyInCommonJSErrorMessagesSet ??= new SafeSet(throwsOnlyInCommonJSErrorMessages);
346+
if (throwsOnlyInCommonJSErrorMessagesSet.has(errorMessage)) {
347+
return /** @type {boolean} */(contextifyShouldRetryAsESM(source));
348348
}
349349

350350
return false;

src/node_contextify.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1728,6 +1728,7 @@ static void CreatePerContextProperties(Local<Object> target,
17281728
Local<Object> constants = Object::New(env->isolate());
17291729
Local<Object> measure_memory = Object::New(env->isolate());
17301730
Local<Object> memory_execution = Object::New(env->isolate());
1731+
Local<Object> syntax_detection_errors = Object::New(env->isolate());
17311732

17321733
{
17331734
Local<Object> memory_mode = Object::New(env->isolate());
@@ -1748,6 +1749,40 @@ static void CreatePerContextProperties(Local<Object> target,
17481749

17491750
READONLY_PROPERTY(constants, "measureMemory", measure_memory);
17501751

1752+
{
1753+
Local<Array> esm_syntax_error_messages_array =
1754+
Array::New(env->isolate(), esm_syntax_error_messages.size());
1755+
for (size_t i = 0; i < esm_syntax_error_messages.size(); i++) {
1756+
const char* message = esm_syntax_error_messages[i].data();
1757+
(void)esm_syntax_error_messages_array->Set(
1758+
context,
1759+
static_cast<uint32_t>(i),
1760+
String::NewFromUtf8(env->isolate(), message)
1761+
.ToLocalChecked());
1762+
}
1763+
READONLY_PROPERTY(syntax_detection_errors, "esmSyntaxErrorMessages",
1764+
esm_syntax_error_messages_array);
1765+
}
1766+
1767+
{
1768+
Local<Array> throws_only_in_cjs_error_messages_array =
1769+
Array::New(env->isolate(), throws_only_in_cjs_error_messages.size());
1770+
for (size_t i = 0; i < throws_only_in_cjs_error_messages.size(); i++) {
1771+
const char* message = throws_only_in_cjs_error_messages[i].data();
1772+
(void)throws_only_in_cjs_error_messages_array->Set(
1773+
context,
1774+
static_cast<uint32_t>(i),
1775+
String::NewFromUtf8(env->isolate(), message)
1776+
.ToLocalChecked());
1777+
}
1778+
READONLY_PROPERTY(syntax_detection_errors,
1779+
"throwsOnlyInCommonJSErrorMessages",
1780+
throws_only_in_cjs_error_messages_array);
1781+
}
1782+
1783+
READONLY_PROPERTY(constants, "syntaxDetectionErrors",
1784+
syntax_detection_errors);
1785+
17511786
target->Set(context, env->constants_string(), constants).Check();
17521787
}
17531788

0 commit comments

Comments
 (0)