node-internal-errors.js 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. 'use strict';
  2. const path = require('path');
  3. exports.codes = {
  4. ERR_INPUT_TYPE_NOT_ALLOWED: createErrorCtor(joinArgs('ERR_INPUT_TYPE_NOT_ALLOWED')),
  5. ERR_INVALID_ARG_VALUE: createErrorCtor(joinArgs('ERR_INVALID_ARG_VALUE')),
  6. ERR_INVALID_MODULE_SPECIFIER: createErrorCtor(joinArgs('ERR_INVALID_MODULE_SPECIFIER')),
  7. ERR_INVALID_PACKAGE_CONFIG: createErrorCtor(joinArgs('ERR_INVALID_PACKAGE_CONFIG')),
  8. ERR_INVALID_PACKAGE_TARGET: createErrorCtor(joinArgs('ERR_INVALID_PACKAGE_TARGET')),
  9. ERR_MANIFEST_DEPENDENCY_MISSING: createErrorCtor(joinArgs('ERR_MANIFEST_DEPENDENCY_MISSING')),
  10. ERR_MODULE_NOT_FOUND: createErrorCtor((path, base, type = 'package') => {
  11. return `Cannot find ${type} '${path}' imported from ${base}`
  12. }),
  13. ERR_PACKAGE_IMPORT_NOT_DEFINED: createErrorCtor(joinArgs('ERR_PACKAGE_IMPORT_NOT_DEFINED')),
  14. ERR_PACKAGE_PATH_NOT_EXPORTED: createErrorCtor(joinArgs('ERR_PACKAGE_PATH_NOT_EXPORTED')),
  15. ERR_UNSUPPORTED_DIR_IMPORT: createErrorCtor(joinArgs('ERR_UNSUPPORTED_DIR_IMPORT')),
  16. ERR_UNSUPPORTED_ESM_URL_SCHEME: createErrorCtor(joinArgs('ERR_UNSUPPORTED_ESM_URL_SCHEME')),
  17. ERR_UNKNOWN_FILE_EXTENSION: createErrorCtor(joinArgs('ERR_UNKNOWN_FILE_EXTENSION')),
  18. }
  19. function joinArgs(name) {
  20. return (...args) => {
  21. return [name, ...args].join(' ')
  22. }
  23. }
  24. function createErrorCtor(errorMessageCreator) {
  25. return class CustomError extends Error {
  26. constructor(...args) {
  27. super(errorMessageCreator(...args))
  28. }
  29. }
  30. }
  31. exports.createErrRequireEsm = createErrRequireEsm;
  32. // Native ERR_REQUIRE_ESM Error is declared here:
  33. // https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L1294-L1313
  34. // Error class factory is implemented here:
  35. // function E: https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L323-L341
  36. // function makeNodeErrorWithCode: https://github.com/nodejs/node/blob/2d5d77306f6dff9110c1f77fefab25f973415770/lib/internal/errors.js#L251-L278
  37. // The code below should create an error that matches the native error as closely as possible.
  38. // Third-party libraries which attempt to catch the native ERR_REQUIRE_ESM should recognize our imitation error.
  39. function createErrRequireEsm(filename, parentPath, packageJsonPath) {
  40. const code = 'ERR_REQUIRE_ESM'
  41. const err = new Error(getErrRequireEsmMessage(filename, parentPath, packageJsonPath))
  42. // Set `name` to be used in stack trace, generate stack trace with that name baked in, then re-declare the `name` field.
  43. // This trick is copied from node's source.
  44. err.name = `Error [${ code }]`
  45. err.stack
  46. Object.defineProperty(err, 'name', {
  47. value: 'Error',
  48. enumerable: false,
  49. writable: true,
  50. configurable: true
  51. })
  52. err.code = code
  53. return err
  54. }
  55. // Copy-pasted from https://github.com/nodejs/node/blob/b533fb3508009e5f567cc776daba8fbf665386a6/lib/internal/errors.js#L1293-L1311
  56. // so that our error message is identical to the native message.
  57. function getErrRequireEsmMessage(filename, parentPath = null, packageJsonPath = null) {
  58. const ext = path.extname(filename)
  59. let msg = `Must use import to load ES Module: ${filename}`;
  60. if (parentPath && packageJsonPath) {
  61. const path = require('path');
  62. const basename = path.basename(filename) === path.basename(parentPath) ?
  63. filename : path.basename(filename);
  64. msg +=
  65. '\nrequire() of ES modules is not supported.\nrequire() of ' +
  66. `${filename} ${parentPath ? `from ${parentPath} ` : ''}` +
  67. `is an ES module file as it is a ${ext} file whose nearest parent ` +
  68. `package.json contains "type": "module" which defines all ${ext} ` +
  69. 'files in that package scope as ES modules.\nInstead ' +
  70. 'change the requiring code to use ' +
  71. 'import(), or remove "type": "module" from ' +
  72. `${packageJsonPath}.\n`;
  73. return msg;
  74. }
  75. return msg;
  76. }