Repository: nodejs/node
Pull request: module: clarify cjs global-like error on ModuleJobSync

This PR copies the error message used for cjs global-like import errors from `ModuleJob` to `ModuleJobSync` to cover more cases.

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: lib/internal/modules/esm/module_job.js
patch: @@ -65,6 +65,37 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
     (globalLike) => errorMessage === `${globalLike} is not defined`,
   );
 
+
+/**
+ *
+ * @param {Error} e
+ * @param {string} url
+ * @returns {void}
+ */
+const explainCommonJSGlobalLikeNotDefinedError = (e, url) => {
+  if (e?.name === 'ReferenceError' &&
+      isCommonJSGlobalLikeNotDefinedError(e.message)) {
+    e.message += ' in ES module scope';
+
+    if (StringPrototypeStartsWith(e.message, 'require ')) {
+      e.message += ', you can use import instead';
+    }
+
+    const packageConfig =
+      StringPrototypeStartsWith(url, 'file://') &&
+        RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, url) !== null &&
+        require('internal/modules/package_json_reader')
+          .getPackageScopeConfig(url);
+    if (packageConfig.type === 'module') {
+      e.message +=
+        '\nThis file is being treated as an ES module because it has a ' +
+        `'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
+        '"type": "module". To treat it as a CommonJS script, rename it ' +
+        'to use the \'.cjs\' file extension.';
+    }
+  }
+};
+
 class ModuleJobBase {
   constructor(url, importAttributes, phase, isMain, inspectBrk) {
     assert(typeof phase === 'number');
@@ -326,27 +357,7 @@ class ModuleJob extends ModuleJobBase {
     try {
       await this.module.evaluate(timeout, breakOnSigint);
     } catch (e) {
-      if (e?.name === 'ReferenceError' &&
-          isCommonJSGlobalLikeNotDefinedError(e.message)) {
-        e.message += ' in ES module scope';
-
-        if (StringPrototypeStartsWith(e.message, 'require ')) {
-          e.message += ', you can use import instead';
-        }
-
-        const packageConfig =
-          StringPrototypeStartsWith(this.module.url, 'file://') &&
-            RegExpPrototypeExec(/\.js(\?[^#]*)?(#.*)?$/, this.module.url) !== null &&
-            require('internal/modules/package_json_reader')
-              .getPackageScopeConfig(this.module.url);
-        if (packageConfig.type === 'module') {
-          e.message +=
-            '\nThis file is being treated as an ES module because it has a ' +
-            `'.js' file extension and '${packageConfig.pjsonPath}' contains ` +
-            '"type": "module". To treat it as a CommonJS script, rename it ' +
-            'to use the \'.cjs\' file extension.';
-        }
-      }
+      explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
       throw e;
     }
     return { __proto__: null, module: this.module };
@@ -476,8 +487,13 @@ class ModuleJobSync extends ModuleJobBase {
       throw new ERR_REQUIRE_ASYNC_MODULE(filename, parentFilename);
     }
     setHasStartedUserESMExecution();
-    const namespace = this.module.evaluateSync(filename, parentFilename);
-    return { __proto__: null, module: this.module, namespace };
+    try {
+      const namespace = this.module.evaluateSync(filename, parentFilename);
+      return { __proto__: null, module: this.module, namespace };
+    } catch (e) {
+      explainCommonJSGlobalLikeNotDefinedError(e, this.module.url);
+      throw e;
+    }
   }
 }
 

filename: test/es-module/test-require-module-error-catching.js
patch: @@ -17,5 +17,5 @@ assert.throws(() => {
   require('../fixtures/es-modules/reference-error-esm.js');
 }, {
   name: 'ReferenceError',
-  message: 'exports is not defined'
+  message: 'exports is not defined in ES module scope'
 });