Skip to content

Commit 6830821

Browse files
authored
ESM: fix swallowing MODULE_NOT_FOUND errors in case of type:module (#4687)
1 parent 5c59da0 commit 6830821

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed

lib/esm-utils.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,21 @@ exports.requireOrImport = hasStableEsmImplementation
5252
err.code === 'ERR_UNKNOWN_FILE_EXTENSION' ||
5353
err.code === 'ERR_UNSUPPORTED_DIR_IMPORT'
5454
) {
55-
return require(file);
55+
try {
56+
return require(file);
57+
} catch (requireErr) {
58+
if (requireErr.code === 'ERR_REQUIRE_ESM') {
59+
// This happens when the test file is a JS file, but via type:module is actually ESM,
60+
// AND has an import to a file that doesn't exist.
61+
// This throws an `ERR_MODULE_NOT_FOUND` // error above,
62+
// and when we try to `require` it here, it throws an `ERR_REQUIRE_ESM`.
63+
// What we want to do is throw the original error (the `ERR_MODULE_NOT_FOUND`),
64+
// and not the `ERR_REQUIRE_ESM` error, which is a red herring.
65+
throw err;
66+
} else {
67+
throw requireErr;
68+
}
69+
}
5670
} else {
5771
throw err;
5872
}

test/integration/esm.spec.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use strict';
22
var path = require('path');
3-
var helpers = require('./helpers');
4-
var run = helpers.runMochaJSON;
5-
var runMochaAsync = helpers.runMochaAsync;
3+
const {runMochaJSON: run, runMochaAsync} = require('./helpers');
64
var utils = require('../../lib/utils');
75
var args =
86
+process.versions.node.split('.')[0] >= 13 ? [] : ['--experimental-modules'];
@@ -81,4 +79,18 @@ describe('esm', function() {
8179

8280
expect(result, 'to have passed test count', 1);
8381
});
82+
83+
it('should throw an ERR_MODULE_NOT_FOUND and not ERR_REQUIRE_ESM if file imports a non-existing module', async function() {
84+
const fixture =
85+
'esm/type-module/test-that-imports-non-existing-module.fixture.js';
86+
87+
const err = await runMochaAsync(fixture, ['--unhandled-rejections=warn'], {
88+
stdio: 'pipe'
89+
}).catch(err => err);
90+
91+
expect(err.output, 'to contain', 'ERR_MODULE_NOT_FOUND').and(
92+
'to contain',
93+
'test-that-imports-non-existing-module'
94+
);
95+
});
8496
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import assert from 'assert';
2+
import './this-module-does-not-exist.js';
3+
4+
it('should not pass (or even run) because above import will fail', () => {
5+
assert(true);
6+
});

0 commit comments

Comments
 (0)