diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index f99d0fc2a7a0eb..5027ecc71cd5a9 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -36,6 +36,7 @@ const { ArrayPrototypeUnshiftApply, Boolean, Error, + ErrorCaptureStackTrace, JSONParse, ObjectDefineProperty, ObjectFreeze, @@ -1674,6 +1675,7 @@ function getRequireESMError(mod, pkg, content, filename) { const usesEsm = containsModuleSyntax(content, filename); const err = new ERR_REQUIRE_ESM(filename, usesEsm, parentPath, packageJsonPath); + ErrorCaptureStackTrace(err, Module.prototype.require); // Attempt to reconstruct the parent require frame. const parentModule = Module._cache[parentPath]; if (parentModule) { diff --git a/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/app.js b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/app.js new file mode 100644 index 00000000000000..72447a44e7ab59 --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/app.js @@ -0,0 +1 @@ +import nothing from 'somewhere'; diff --git a/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/index.cjs b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/index.cjs new file mode 100644 index 00000000000000..f26642639c06c6 --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/index.cjs @@ -0,0 +1,11 @@ +function main() { + func1(func2(func3())) +} + +function func1() { + require('./app.js') +} +function func2() {} +function func3() {} + +main() diff --git a/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/package.json b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/package.json new file mode 100644 index 00000000000000..3dbc1ca591c055 --- /dev/null +++ b/test/fixtures/es-modules/package-type-module/require-esm-error-annotation/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test/parallel/test-require-esm-with-no-experimental-require-module.mjs b/test/parallel/test-require-esm-with-no-experimental-require-module.mjs new file mode 100644 index 00000000000000..9f59c81f161140 --- /dev/null +++ b/test/parallel/test-require-esm-with-no-experimental-require-module.mjs @@ -0,0 +1,24 @@ +import '../common/index.mjs'; +import { test } from 'node:test'; +import * as fixtures from '../common/fixtures.mjs'; +import { spawnSync } from 'node:child_process'; +import assert from 'node:assert'; + +test('correctly reports error for a longer stack trace', () => { + // The following regex matches the error message that is expected to be thrown + // + // package-type-module/require-esm-error-annotation/index.cjs:6 + // require('./app.js') + // ^ + + const fixture = fixtures.path('es-modules/package-type-module/require-esm-error-annotation/index.cjs'); + const args = ['--no-experimental-require-module', fixture]; + const regex = /index\.cjs:6[\n\r]+\s{2}require\('\.\/app\.js'\)[\n\r]+\s{2}\^/; + + const result = spawnSync(process.execPath, args); + const stderr = result.stderr.toString(); + + assert.strictEqual(result.status, 1); + assert.strictEqual(result.stdout.toString(), ''); + assert.match(stderr, regex); +});