Skip to content

Commit 9878f32

Browse files
authored
Add file location when SyntaxError happens in ESM (#4557)
1 parent 84d0c96 commit 9878f32

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

lib/esm-utils.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,29 @@ const url = require('url');
33

44
const formattedImport = async file => {
55
if (path.isAbsolute(file)) {
6-
return import(url.pathToFileURL(file));
6+
try {
7+
return await import(url.pathToFileURL(file));
8+
} catch (err) {
9+
// This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit
10+
// the location of the syntax error in the error thrown.
11+
// This is problematic because the user can't see what file has the problem,
12+
// so we add the file location to the error.
13+
// This `if` should be removed once Node.js fixes the problem.
14+
if (
15+
err instanceof SyntaxError &&
16+
err.message &&
17+
err.stack &&
18+
!err.stack.includes(file)
19+
) {
20+
const newErrorWithFilename = new SyntaxError(err.message);
21+
newErrorWithFilename.stack = err.stack.replace(
22+
/^SyntaxError/,
23+
`SyntaxError[ @${file} ]`
24+
);
25+
throw newErrorWithFilename;
26+
}
27+
throw err;
28+
}
729
}
830
return import(file);
931
};

test/integration/esm.spec.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
'use strict';
2-
var run = require('./helpers').runMochaJSON;
2+
var helpers = require('./helpers');
3+
var run = helpers.runMochaJSON;
4+
var runMochaAsync = helpers.runMochaAsync;
35
var utils = require('../../lib/utils');
46
var args =
57
+process.versions.node.split('.')[0] >= 13 ? [] : ['--experimental-modules'];
@@ -38,6 +40,17 @@ describe('esm', function() {
3840
});
3941
});
4042

43+
it('should show file location when there is a syntax error in the test', async function() {
44+
var fixture = 'esm/syntax-error/esm-syntax-error.fixture.mjs';
45+
const err = await runMochaAsync(fixture, args, {stdio: 'pipe'}).catch(
46+
err => err
47+
);
48+
expect(err.output, 'to contain', 'SyntaxError').and(
49+
'to contain',
50+
'esm-syntax-error.fixture.mjs'
51+
);
52+
});
53+
4154
it('should recognize esm files ending with .js due to package.json type flag', function(done) {
4255
if (!utils.supportsEsModules(false)) return this.skip();
4356

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This is intentionally a syntax error
2+
it('should never run because of a syntax error here', => {
3+
});

0 commit comments

Comments
 (0)