'use strict'; // The whole point behind this internal module is to allow Node.js to no // longer be forced to treat every error message change as a semver-major // change. The NodeError classes here all expose a `code` property whose // value statically and permanently identifies the error. While the error // message may change, the code should not. const assert = require('assert'); const kCode = Symbol('code'); const messages = new Map(); var util; function lazyUtil() { if (!util) util = require('util'); return util; } function makeNodeError(Base) { return class NodeError extends Base { constructor(key, ...args) { super(message(key, args)); this[kCode] = key; Error.captureStackTrace(this, NodeError); } get name() { return `${super.name}[${this[kCode]}]`; } get code() { return this[kCode]; } }; } function message(key, args) { assert.strictEqual(typeof key, 'string'); const util = lazyUtil(); const msg = messages.get(key); assert(msg, `An invalid error message key was used: ${key}.`); let fmt = util.format; if (typeof msg === 'function') { fmt = msg; } else { if (args === undefined || args.length === 0) return msg; args.unshift(msg); } return String(fmt.apply(null, args)); } // Utility function for registering the error codes. Only used here. Exported // *only* to allow for testing. function E(sym, val) { assert(messages.has(sym) === false, `Error symbol: ${sym} was already used.`); messages.set(sym, typeof val === 'function' ? val : String(val)); } module.exports = exports = { message, Error: makeNodeError(Error), TypeError: makeNodeError(TypeError), RangeError: makeNodeError(RangeError), E // This is exported only to facilitate testing. }; // To declare an error message, use the E(sym, val) function above. The sym // must be an upper case string. The val can be either a function or a string. // The return value of the function must be a string. // Examples: // E('EXAMPLE_KEY1', 'This is the error value'); // E('EXAMPLE_KEY2', (a, b) => return `${a} ${b}`); // // Once an error code has been assigned, the code itself MUST NOT change and // any given error code must never be reused to identify a different error. // // Any error code added here should also be added to the documentation // // Note: Please try to keep these in alphabetical order E('ERR_ASSERTION', (msg) => msg); // Add new errors from here...