Skip to content

Commit bbb6cc7

Browse files
guybedfordcodebytere
authored andcommittedFeb 27, 2020
module: package "exports" error refinements
PR-URL: #31625 Reviewed-By: Jan Krems <jan.krems@gmail.com>
1 parent 87e9014 commit bbb6cc7

File tree

10 files changed

+331
-219
lines changed

10 files changed

+331
-219
lines changed
 

‎doc/api/errors.md

+20
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,12 @@ An invalid HTTP token was supplied.
13191319

13201320
An IP address is not valid.
13211321

1322+
<a id="ERR_INVALID_MODULE_SPECIFIER"></a>
1323+
### `ERR_INVALID_MODULE_SPECIFIER`
1324+
1325+
The imported module string is an invalid URL, package name, or package subpath
1326+
specifier.
1327+
13221328
<a id="ERR_INVALID_OPT_VALUE"></a>
13231329
### `ERR_INVALID_OPT_VALUE`
13241330

@@ -1334,6 +1340,12 @@ An invalid or unknown file encoding was passed.
13341340

13351341
An invalid `package.json` file was found which failed parsing.
13361342

1343+
<a id="ERR_INVALID_PACKAGE_TARGET"></a>
1344+
### `ERR_INVALID_PACKAGE_TARGET`
1345+
1346+
The `package.json` [exports][] field contains an invalid target mapping value
1347+
for the attempted module resolution.
1348+
13371349
<a id="ERR_INVALID_PERFORMANCE_MARK"></a>
13381350
### `ERR_INVALID_PERFORMANCE_MARK`
13391351

@@ -1640,6 +1652,13 @@ A non-context-aware native addon was loaded in a process that disallows them.
16401652

16411653
A given value is out of the accepted range.
16421654

1655+
<a id="ERR_PACKAGE_PATH_NOT_EXPORTED"></a>
1656+
### `ERR_PACKAGE_PATH_NOT_EXPORTED`
1657+
1658+
The `package.json` [exports][] field does not export the requested subpath.
1659+
Because exports are encapsulated, private internal modules that are not exported
1660+
cannot be imported through the package resolution, unless using an absolute URL.
1661+
16431662
<a id="ERR_REQUIRE_ESM"></a>
16441663
### `ERR_REQUIRE_ESM`
16451664

@@ -2499,6 +2518,7 @@ such as `process.stdout.on('data')`.
24992518
[crypto digest algorithm]: crypto.html#crypto_crypto_gethashes
25002519
[domains]: domain.html
25012520
[event emitter-based]: events.html#events_class_eventemitter
2521+
[exports]: esm.html#esm_package_exports
25022522
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
25032523
[policy]: policy.html
25042524
[stream-based]: stream.html

‎doc/api/esm.md

+44-31
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,17 @@ of these top-level routines unless stated otherwise.
13911391
_defaultEnv_ is the conditional environment name priority array,
13921392
`["node", "import"]`.
13931393
1394+
The resolver can throw the following errors:
1395+
* _Invalid Module Specifier_: Module specifier is an invalid URL, package name
1396+
or package subpath specifier.
1397+
* _Invalid Package Configuration_: package.json configuration is invalid or
1398+
contains an invalid configuration.
1399+
* _Invalid Package Target_: Package exports define a target module within the
1400+
package that is an invalid type or string target.
1401+
* _Package Path Not Exported_: Package exports do not define or permit a target
1402+
subpath in the package for the given module.
1403+
* _Module Not Found_: The package or module requested does not exist.
1404+
13941405
<details>
13951406
<summary>Resolver algorithm specification</summary>
13961407
@@ -1401,7 +1412,7 @@ _defaultEnv_ is the conditional environment name priority array,
14011412
> 1. Set _resolvedURL_ to the result of parsing and reserializing
14021413
> _specifier_ as a URL.
14031414
> 1. Otherwise, if _specifier_ starts with _"/"_, then
1404-
> 1. Throw an _Invalid Specifier_ error.
1415+
> 1. Throw an _Invalid Module Specifier_ error.
14051416
> 1. Otherwise, if _specifier_ starts with _"./"_ or _"../"_, then
14061417
> 1. Set _resolvedURL_ to the URL resolution of _specifier_ relative to
14071418
> _parentURL_.
@@ -1411,7 +1422,7 @@ _defaultEnv_ is the conditional environment name priority array,
14111422
> **PACKAGE_RESOLVE**(_specifier_, _parentURL_).
14121423
> 1. If _resolvedURL_ contains any percent encodings of _"/"_ or _"\\"_ (_"%2f"_
14131424
> and _"%5C"_ respectively), then
1414-
> 1. Throw an _Invalid Specifier_ error.
1425+
> 1. Throw an _Invalid Module Specifier_ error.
14151426
> 1. If _resolvedURL_ does not end with a trailing _"/"_ and the file at
14161427
> _resolvedURL_ does not exist, then
14171428
> 1. Throw a _Module Not Found_ error.
@@ -1425,22 +1436,22 @@ _defaultEnv_ is the conditional environment name priority array,
14251436
> 1. Let _packageName_ be *undefined*.
14261437
> 1. Let _packageSubpath_ be *undefined*.
14271438
> 1. If _packageSpecifier_ is an empty string, then
1428-
> 1. Throw an _Invalid Specifier_ error.
1439+
> 1. Throw an _Invalid Module Specifier_ error.
14291440
> 1. Otherwise,
14301441
> 1. If _packageSpecifier_ does not contain a _"/"_ separator, then
1431-
> 1. Throw an _Invalid Specifier_ error.
1442+
> 1. Throw an _Invalid Module Specifier_ error.
14321443
> 1. Set _packageName_ to the substring of _packageSpecifier_
14331444
> until the second _"/"_ separator or the end of the string.
14341445
> 1. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then
1435-
> 1. Throw an _Invalid Specifier_ error.
1446+
> 1. Throw an _Invalid Module Specifier_ error.
14361447
> 1. Let _packageSubpath_ be _undefined_.
14371448
> 1. If the length of _packageSpecifier_ is greater than the length of
14381449
> _packageName_, then
14391450
> 1. Set _packageSubpath_ to _"."_ concatenated with the substring of
14401451
> _packageSpecifier_ from the position at the length of _packageName_.
14411452
> 1. If _packageSubpath_ contains any _"."_ or _".."_ segments or percent
14421453
> encoded strings for _"/"_ or _"\\"_, then
1443-
> 1. Throw an _Invalid Specifier_ error.
1454+
> 1. Throw an _Invalid Module Specifier_ error.
14441455
> 1. Set _selfUrl_ to the result of
14451456
> **SELF_REFERENCE_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_).
14461457
> 1. If _selfUrl_ isn't empty, return _selfUrl_.
@@ -1497,7 +1508,7 @@ _defaultEnv_ is the conditional environment name priority array,
14971508
> 1. Throw a _Module Not Found_ error.
14981509
> 1. If _pjson.exports_ is not **null** or **undefined**, then
14991510
> 1. If _exports_ is an Object with both a key starting with _"."_ and a key
1500-
> not starting with _"."_, throw an "Invalid Package Configuration" error.
1511+
> not starting with _"."_, throw an _Invalid Package Configuration_ error.
15011512
> 1. If _pjson.exports_ is a String or Array, or an Object containing no
15021513
> keys starting with _"."_, then
15031514
> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_,
@@ -1506,6 +1517,7 @@ _defaultEnv_ is the conditional environment name priority array,
15061517
> 1. Let _mainExport_ be the _"."_ property in _pjson.exports_.
15071518
> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_,
15081519
> _mainExport_, _""_).
1520+
> 1. Throw a _Package Path Not Exported_ error.
15091521
> 1. If _pjson.main_ is a String, then
15101522
> 1. Let _resolvedMain_ be the URL resolution of _packageURL_, "/", and
15111523
> _pjson.main_.
@@ -1520,7 +1532,7 @@ _defaultEnv_ is the conditional environment name priority array,
15201532
15211533
**PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _packagePath_, _exports_)
15221534
> 1. If _exports_ is an Object with both a key starting with _"."_ and a key not
1523-
> starting with _"."_, throw an "Invalid Package Configuration" error.
1535+
> starting with _"."_, throw an _Invalid Package Configuration_ error.
15241536
> 1. If _exports_ is an Object and all keys of _exports_ start with _"."_, then
15251537
> 1. Set _packagePath_ to _"./"_ concatenated with _packagePath_.
15261538
> 1. If _packagePath_ is a key of _exports_, then
@@ -1536,43 +1548,44 @@ _defaultEnv_ is the conditional environment name priority array,
15361548
> of the length of _directory_.
15371549
> 1. Return **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_,
15381550
> _subpath_, _defaultEnv_).
1539-
> 1. Throw a _Module Not Found_ error.
1551+
> 1. Throw a _Package Path Not Exported_ error.
15401552
15411553
**PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _target_, _subpath_, _env_)
15421554
1543-
> 1. If _target_ is a String, then
1544-
> 1. If _target_ does not start with _"./"_, throw a _Module Not Found_
1545-
> error.
1546-
> 1. If _subpath_ has non-zero length and _target_ does not end with _"/"_,
1547-
> throw a _Module Not Found_ error.
1548-
> 1. If _target_ or _subpath_ contain any _"node_modules"_ segments including
1549-
> _"node_modules"_ percent-encoding, throw a _Module Not Found_ error.
1555+
> 1.If _target_ is a String, then
1556+
> 1. If _target_ does not start with _"./"_ or contains any _"node_modules"_
1557+
> segments including _"node_modules"_ percent-encoding, throw an
1558+
> _Invalid Package Target_ error.
15501559
> 1. Let _resolvedTarget_ be the URL resolution of the concatenation of
15511560
> _packageURL_ and _target_.
1552-
> 1. If _resolvedTarget_ is contained in _packageURL_, then
1553-
> 1. Let _resolved_ be the URL resolution of the concatenation of
1554-
> _subpath_ and _resolvedTarget_.
1555-
> 1. If _resolved_ is contained in _resolvedTarget_, then
1556-
> 1. Return _resolved_.
1561+
> 1. If _resolvedTarget_ is not contained in _packageURL_, throw an
1562+
> _Invalid Package Target_ error.
1563+
> 1. If _subpath_ has non-zero length and _target_ does not end with _"/"_,
1564+
> throw an _Invalid Module Specifier_ error.
1565+
> 1. Let _resolved_ be the URL resolution of the concatenation of
1566+
> _subpath_ and _resolvedTarget_.
1567+
> 1. If _resolved_ is not contained in _resolvedTarget_, throw an
1568+
> _Invalid Module Specifier_ error.
1569+
> 1. Return _resolved_.
15571570
> 1. Otherwise, if _target_ is a non-null Object, then
15581571
> 1. If _exports_ contains any index property keys, as defined in ECMA-262
15591572
> [6.1.7 Array Index][], throw an _Invalid Package Configuration_ error.
15601573
> 1. For each property _p_ of _target_, in object insertion order as,
15611574
> 1. If _env_ contains an entry for _p_, then
15621575
> 1. Let _targetValue_ be the value of the _p_ property in _target_.
1563-
> 1. Let _resolved_ be the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**
1564-
> (_packageURL_, _targetValue_, _subpath_, _env_).
1565-
> 1. Assert: _resolved_ is a String.
1566-
> 1. Return _resolved_.
1576+
> 1. Return the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**(
1577+
> _packageURL_, _targetValue_, _subpath_, _env_), continuing the
1578+
> loop on any _Package Path Not Exported_ error.
1579+
> 1. Throw a _Package Path Not Exported_ error.
15671580
> 1. Otherwise, if _target_ is an Array, then
1581+
> 1. If _target.length is zero, throw an _Invalid Package Target_ error.
15681582
> 1. For each item _targetValue_ in _target_, do
15691583
> 1. If _targetValue_ is an Array, continue the loop.
1570-
> 1. Let _resolved_ be the result of
1571-
> **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_, _targetValue_,
1572-
> _subpath_, _env_), continuing the loop on abrupt completion.
1573-
> 1. Assert: _resolved_ is a String.
1574-
> 1. Return _resolved_.
1575-
> 1. Throw a _Module Not Found_ error.
1584+
> 1. Return the result of **PACKAGE_EXPORTS_TARGET_RESOLVE**(_packageURL_,
1585+
> _targetValue_, _subpath_, _env_), continuing the loop on any
1586+
> _Package Path Not Exported_ or _Invalid Package Target_ error.
1587+
> 1. Throw the last fallback resolution error.
1588+
> 1. Otherwise throw an _Invalid Package Target_ error.
15761589
15771590
**ESM_FORMAT**(_url_)
15781591

‎lib/internal/errors.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,20 @@
1313
const {
1414
ArrayIsArray,
1515
Error,
16+
JSONStringify,
1617
Map,
1718
MathAbs,
1819
NumberIsInteger,
1920
ObjectDefineProperty,
2021
ObjectKeys,
22+
StringPrototypeSlice,
2123
Symbol,
2224
SymbolFor,
2325
WeakMap,
2426
} = primordials;
2527

28+
const sep = process.platform === 'win32' ? '\\' : '/';
29+
2630
const messages = new Map();
2731
const codes = {};
2832

@@ -1069,14 +1073,29 @@ E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s', TypeError);
10691073
E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent', TypeError);
10701074
E('ERR_INVALID_HTTP_TOKEN', '%s must be a valid HTTP token ["%s"]', TypeError);
10711075
E('ERR_INVALID_IP_ADDRESS', 'Invalid IP address: %s', TypeError);
1076+
E('ERR_INVALID_MODULE_SPECIFIER', (pkgPath, subpath) => {
1077+
assert(subpath !== '.');
1078+
return `Package subpath '${subpath}' is not a valid module request for the ` +
1079+
`"exports" resolution of ${pkgPath}${sep}package.json`;
1080+
}, TypeError);
10721081
E('ERR_INVALID_OPT_VALUE', (name, value) =>
10731082
`The value "${String(value)}" is invalid for option "${name}"`,
10741083
TypeError,
10751084
RangeError);
10761085
E('ERR_INVALID_OPT_VALUE_ENCODING',
10771086
'The value "%s" is invalid for option "encoding"', TypeError);
10781087
E('ERR_INVALID_PACKAGE_CONFIG',
1079-
'Invalid package config for \'%s\', %s', Error);
1088+
`Invalid package config %s${sep}package.json, %s`, Error);
1089+
E('ERR_INVALID_PACKAGE_TARGET', (pkgPath, key, subpath, target) => {
1090+
if (key === '.') {
1091+
return `Invalid "exports" main target ${JSONStringify(target)} defined ` +
1092+
`in the package config ${pkgPath}${sep}package.json`;
1093+
} else {
1094+
return `Invalid "exports" target ${JSONStringify(target)} defined for '${
1095+
StringPrototypeSlice(key, 0, -subpath.length || key.length)}' in the ` +
1096+
`package config ${pkgPath}${sep}package.json`;
1097+
}
1098+
}, Error);
10801099
E('ERR_INVALID_PERFORMANCE_MARK',
10811100
'The "%s" performance mark has not been set', Error);
10821101
E('ERR_INVALID_PROTOCOL',
@@ -1221,6 +1240,14 @@ E('ERR_OUT_OF_RANGE',
12211240
msg += ` It must be ${range}. Received ${received}`;
12221241
return msg;
12231242
}, RangeError);
1243+
E('ERR_PACKAGE_PATH_NOT_EXPORTED', (pkgPath, subpath) => {
1244+
if (subpath === '.') {
1245+
return `No "exports" main resolved in ${pkgPath}${sep}package.json`;
1246+
} else {
1247+
return `Package subpath '${subpath}' is not defined by "exports" in ${
1248+
pkgPath}${sep}package.json`;
1249+
}
1250+
}, Error);
12241251
E('ERR_REQUIRE_ESM',
12251252
(filename, parentPath = null, packageJsonPath = null) => {
12261253
let msg = `Must use import to load ES Module: ${filename}`;

0 commit comments

Comments
 (0)
Please sign in to comment.