diff --git a/lib/nodejs/esm-utils.cjs b/lib/nodejs/esm-utils.cjs index 31c666952a..34b2e09a44 100644 --- a/lib/nodejs/esm-utils.cjs +++ b/lib/nodejs/esm-utils.cjs @@ -116,6 +116,13 @@ const requireModule = async (file, esmDecorator) => { throw requireErr; } + // A directory specifier resolves under CommonJS but not under ESM so this error + // only means the fallback import() never got far enough to say anything useful about the file. + // Check this issue https://github.com/mochajs/mocha/issues/5792 + if (importErr.code === "ERR_UNSUPPORTED_DIR_IMPORT") { + throw requireErr; + } + // Similarly, for an exports/imports mismatch such as a missing 'default', // the require() error will be more informative for users. // See: https://github.com/mochajs/mocha/issues/5411 diff --git a/test/node-unit/esm-utils.spec.cjs b/test/node-unit/esm-utils.spec.cjs index f5d3184349..d8194828e6 100644 --- a/test/node-unit/esm-utils.spec.cjs +++ b/test/node-unit/esm-utils.spec.cjs @@ -6,6 +6,10 @@ const url = require("node:url"); describe("esm-utils", function () { describe("requireOrImport", function () { + afterEach(function () { + sinon.restore(); + }); + it("should show an informative error message for a broken default import", async function () { return expect( () => @@ -62,6 +66,29 @@ describe("esm-utils", function () { }, ); }); + + it("should surface the require() error when import() fails on a directory specifier", async function () { + sinon + .stub(esmUtils, "doImport") + .rejects( + Object.assign( + new Error("Directory import '/fixtures/lib' is not supported"), + { code: "ERR_UNSUPPORTED_DIR_IMPORT" }, + ), + ); + + return expect( + () => + esmUtils.requireOrImport( + "../../test/node-unit/fixtures/this-module-does-not-exist.cjs", + ), + "to be rejected with error satisfying", + { + code: "MODULE_NOT_FOUND", + message: /this-module-does-not-exist/, + }, + ); + }); }); describe("loadFilesAsync()", function () {