diff --git a/doc/api/errors.md b/doc/api/errors.md
index 640935da35e460..38ce52dea0e240 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -563,6 +563,15 @@ found [here][online].
encountered by [`http`][] or [`net`][] -- often a sign that a `socket.end()`
was not properly called.
+
+## Node.js Error Codes
+
+
+### ERR_INVALID_ARG_TYPE
+
+The `'ERR_INVALID_ARG_TYPE'` error code is used generically to identify that
+an argument of the wrong type has been passed to a Node.js API.
+
[`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
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index f2376f70371c60..03c7cc902e32bc 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -86,3 +86,28 @@ module.exports = exports = {
// Note: Please try to keep these in alphabetical order
E('ERR_ASSERTION', (msg) => msg);
// Add new errors from here...
+E('ERR_INVALID_ARG_TYPE', invalidArgType);
+// Add new errors from here...
+
+function invalidArgType(name, expected, actual) {
+ const assert = lazyAssert();
+ assert(name, 'name is required');
+ assert(expected, 'expected is required');
+ var msg = `The "${name}" argument must be `;
+ if (Array.isArray(expected)) {
+ var len = expected.length;
+ expected = expected.map((i) => String(i));
+ if (len > 1) {
+ msg += `one of type ${expected.slice(0, len - 1).join(', ')}/
+, or ${expected[len - 1]}`;
+ } else {
+ msg += `type ${String(expected[0])}`;
+ }
+ } else {
+ msg += `type ${String(expected)}`;
+ }
+ if (arguments.length >= 3) {
+ msg += `. Received type ${actual === null ? 'null' : typeof actual}`;
+ }
+ return msg;
+}
diff --git a/lib/url.js b/lib/url.js
index 57f04d5f3fccac..bca937df460eb3 100644
--- a/lib/url.js
+++ b/lib/url.js
@@ -10,6 +10,7 @@ function importPunycode() {
const { toASCII } = importPunycode();
+const errors = require('internal/errors');
const internalUrl = require('internal/url');
const encodeAuth = internalUrl.encodeAuth;
exports.parse = urlParse;
@@ -92,7 +93,7 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
if (typeof url !== 'string') {
- throw new TypeError('Parameter "url" must be a string, not ' + typeof url);
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'url', 'String', url);
}
// Copy chrome, IE, opera backslash-handling behavior.
@@ -546,8 +547,7 @@ function urlFormat(obj, options) {
if (typeof obj === 'string') {
obj = urlParse(obj);
} else if (typeof obj !== 'object' || obj === null) {
- throw new TypeError('Parameter "urlObj" must be an object, not ' +
- (obj === null ? 'null' : typeof obj));
+ throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'obj', 'Object', obj);
} else if (!(obj instanceof Url)) {
var format = obj[internalUrl.formatSymbol];
return format ?