diff --git a/doc/api/errors.md b/doc/api/errors.md
index 96409a53677689..c1a371fa85a83c 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -255,6 +255,13 @@ will affect any stack trace captured *after* the value has been changed.
If set to a non-number value, or set to a negative number, stack traces will
not capture any frames.
+#### error.code
+
+* {string}
+
+The `error.code` property is a string label that identifies the kind of error.
+See [Node.js Error Codes][] for details about specific codes.
+
### error.message
* {string}
@@ -550,6 +557,15 @@ found [here][online].
encountered by [`http`][] or [`net`][] -- often a sign that a `socket.end()`
was not properly called.
+
+## Node.js Error Codes
+
+
+### MODULE_NOT_FOUND
+
+The `'MODULE_NOT_FOUND'` error is thrown if `require()` is called on
+file that does not exist.
+
[`fs.readdir`]: fs.html#fs_fs_readdir_path_options_callback
[`fs.readFileSync`]: fs.html#fs_fs_readfilesync_file_options
[`fs.unlink`]: fs.html#fs_fs_unlink_path_callback
@@ -562,6 +578,7 @@ found [here][online].
[domains]: domain.html
[event emitter-based]: events.html#events_class_eventemitter
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
+[Node.js Error Codes]: #nodejs-error-codes
[online]: http://man7.org/linux/man-pages/man3/errno.3.html
[stream-based]: stream.html
[syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 3cab1409422d6f..4f43f1e7dfb501 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -88,3 +88,7 @@ module.exports = exports = {
// Note: Please try to keep these in alphabetical order
E('ERR_ASSERTION', (msg) => msg);
// Add new errors from here...
+E('MODULE_NOT_FOUND', (request) => `Cannot find module '${request}'`);
+E('ERR_PARSING_JSON', (filePath, message) => (
+ `Error parsing '${filePath}': ${message}`
+));
diff --git a/lib/module.js b/lib/module.js
index d9442a62b7c372..edb0c3fe4cc02a 100644
--- a/lib/module.js
+++ b/lib/module.js
@@ -23,6 +23,7 @@
const NativeModule = require('native_module');
const util = require('util');
+const errors = require('internal/errors');
const internalModule = require('internal/module');
const vm = require('vm');
const assert = require('assert').ok;
@@ -482,8 +483,7 @@ Module._resolveFilename = function(request, parent, isMain) {
// look up the filename first, since that's the cache key.
var filename = Module._findPath(request, paths, isMain);
if (!filename) {
- var err = new Error(`Cannot find module '${request}'`);
- err.code = 'MODULE_NOT_FOUND';
+ const err = new errors.Error('MODULE_NOT_FOUND', request);
throw err;
}
return filename;
diff --git a/test/parallel/test-cli-syntax.js b/test/parallel/test-cli-syntax.js
index d7781eddffbb42..c94780e6293933 100644
--- a/test/parallel/test-cli-syntax.js
+++ b/test/parallel/test-cli-syntax.js
@@ -4,6 +4,7 @@ const common = require('../common');
const assert = require('assert');
const spawnSync = require('child_process').spawnSync;
const path = require('path');
+const errors = require('../../lib/internal/errors');
const node = process.execPath;
@@ -76,7 +77,8 @@ const syntaxArgs = [
assert.strictEqual(c.stdout, '', 'stdout produced');
// stderr should have a module not found error message
- const match = c.stderr.match(/^Error: Cannot find module/m);
+ const expectedError = new errors.Error('MODULE_NOT_FOUND', file);
+ const match = c.stderr.match(expectedError.message);
assert(match, 'stderr incorrect');
assert.strictEqual(c.status, 1, 'code == ' + c.status);
diff --git a/test/parallel/test-internal-modules.js b/test/parallel/test-internal-modules.js
index 2f11ca18dd6b34..014edba89b09a9 100644
--- a/test/parallel/test-internal-modules.js
+++ b/test/parallel/test-internal-modules.js
@@ -2,10 +2,13 @@
const common = require('../common');
const path = require('path');
const assert = require('assert');
+const errors = require('../../lib/internal/errors');
+const internalModuleName = 'internal/freelist';
+const expectedError = new errors.Error('MODULE_NOT_FOUND', internalModuleName);
assert.throws(function() {
- require('internal/freelist');
-}, /^Error: Cannot find module 'internal\/freelist'$/);
+ require(internalModuleName);
+}, new RegExp(expectedError.message));
assert.strictEqual(
require(path.join(common.fixturesDir, 'internal-modules')),
diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js
index b6de19856985ed..20eebcad808fdd 100644
--- a/test/parallel/test-repl.js
+++ b/test/parallel/test-repl.js
@@ -23,6 +23,7 @@
'use strict';
const common = require('../common');
const assert = require('assert');
+const errors = require('../../lib/internal/errors');
common.globalCheck = false;
common.refreshTmpDir();
@@ -343,8 +344,10 @@ function error_test() {
expect: 'undefined\n' + prompt_unix },
// REPL should get a normal require() function, not one that allows
// access to internal modules without the --expose_internals flag.
- { client: client_unix, send: 'require("internal/repl")',
- expect: /^Error: Cannot find module 'internal\/repl'/ },
+ {
+ client: client_unix, send: 'require("internal/repl")',
+ expect: new RegExp(new errors.Error('MODULE_NOT_FOUND', 'internal/repl').message)
+ },
// REPL should handle quotes within regexp literal in multiline mode
{ client: client_unix,
send: "function x(s) {\nreturn s.replace(/'/,'');\n}",
diff --git a/test/sequential/test-module-loading.js b/test/sequential/test-module-loading.js
index 1894bc20165b14..bd1714b66feb2b 100644
--- a/test/sequential/test-module-loading.js
+++ b/test/sequential/test-module-loading.js
@@ -24,6 +24,7 @@ require('../common');
const assert = require('assert');
const path = require('path');
const fs = require('fs');
+const errors = require('../../lib/internal/errors');
console.error('load test-module-loading.js');
@@ -120,8 +121,10 @@ console.error('test name clashes');
const my_path = require('../fixtures/path');
assert.ok(my_path.path_func instanceof Function);
// this one does not exist and should throw
-assert.throws(function() { require('./utils'); },
- /^Error: Cannot find module '.\/utils'$/);
+const notFoundPath = './utils';
+const notFoundError = new errors.Error('MODULE_NOT_FOUND', notFoundPath);
+assert.throws(function() { require(notFoundPath); },
+ new RegExp(notFoundError.message));
let errorThrown = false;
try {
@@ -224,6 +227,7 @@ const children = module.children.reduce(function red(set, child) {
assert.deepStrictEqual(children, {
'common.js': {},
+ '../lib/internal/errors.js': {},
'fixtures/not-main-module.js': {},
'fixtures/a.js': {
'fixtures/b/c.js': {