11cb0ef41Sopenharmony_ci# Using the internal/errors.js module 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci## What is internal/errors.js 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciThe `require('internal/errors')` module is an internal-only module that can be 61cb0ef41Sopenharmony_ciused to produce `Error`, `TypeError` and `RangeError` instances that use a 71cb0ef41Sopenharmony_cistatic, permanent error code and an optionally parameterized message. 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciThe intent of the module is to allow errors provided by Node.js to be assigned a 101cb0ef41Sopenharmony_cipermanent identifier. Without a permanent identifier, userland code may need to 111cb0ef41Sopenharmony_ciinspect error messages to distinguish one error from another. An unfortunate 121cb0ef41Sopenharmony_ciresult of that practice is that changes to error messages result in broken code 131cb0ef41Sopenharmony_ciin the ecosystem. For that reason, Node.js has considered error message changes 141cb0ef41Sopenharmony_cito be breaking changes. By providing a permanent identifier for a specific 151cb0ef41Sopenharmony_cierror, we reduce the need for userland code to inspect error messages. 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ciSwitching an existing error to use the `internal/errors` module must be 181cb0ef41Sopenharmony_ciconsidered a `semver-major` change. 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_ci## Using internal/errors.js 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ciThe `internal/errors` module exposes all custom errors as subclasses of the 231cb0ef41Sopenharmony_cibuiltin errors. After being added, an error can be found in the `codes` object. 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ciFor instance, an existing `Error` such as: 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci```js 281cb0ef41Sopenharmony_ciconst err = new TypeError(`Expected string received ${type}`); 291cb0ef41Sopenharmony_ci``` 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ciCan be replaced by first adding a new error key into the `internal/errors.js` 321cb0ef41Sopenharmony_cifile: 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci```js 351cb0ef41Sopenharmony_ciE('FOO', 'Expected string received %s', TypeError); 361cb0ef41Sopenharmony_ci``` 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ciThen replacing the existing `new TypeError` in the code: 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci```js 411cb0ef41Sopenharmony_ciconst { FOO } = require('internal/errors').codes; 421cb0ef41Sopenharmony_ci// ... 431cb0ef41Sopenharmony_ciconst err = new FOO(type); 441cb0ef41Sopenharmony_ci``` 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci## Adding new errors 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ciNew static error codes are added by modifying the `internal/errors.js` file 491cb0ef41Sopenharmony_ciand appending the new error codes to the end using the utility `E()` method. 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci```js 521cb0ef41Sopenharmony_ciE('EXAMPLE_KEY1', 'This is the error value', TypeError); 531cb0ef41Sopenharmony_ciE('EXAMPLE_KEY2', (a, b) => `${a} ${b}`, RangeError); 541cb0ef41Sopenharmony_ci``` 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ciThe first argument passed to `E()` is the static identifier. The second 571cb0ef41Sopenharmony_ciargument is either a String with optional `util.format()` style replacement 581cb0ef41Sopenharmony_citags (e.g. `%s`, `%d`), or a function returning a String. The optional 591cb0ef41Sopenharmony_ciadditional arguments passed to the `errors.message()` function (which is 601cb0ef41Sopenharmony_ciused by the `errors.Error`, `errors.TypeError` and `errors.RangeError` classes), 611cb0ef41Sopenharmony_ciwill be used to format the error message. The third argument is the base class 621cb0ef41Sopenharmony_cithat the new error will extend. 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ciIt is possible to create multiple derived 651cb0ef41Sopenharmony_ciclasses by providing additional arguments. The other ones will be exposed as 661cb0ef41Sopenharmony_ciproperties of the main class: 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci<!-- eslint-disable no-unreachable --> 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci```js 711cb0ef41Sopenharmony_ciE('EXAMPLE_KEY', 'Error message', TypeError, RangeError); 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci// In another module 741cb0ef41Sopenharmony_ciconst { EXAMPLE_KEY } = require('internal/errors').codes; 751cb0ef41Sopenharmony_ci// TypeError 761cb0ef41Sopenharmony_cithrow new EXAMPLE_KEY(); 771cb0ef41Sopenharmony_ci// RangeError 781cb0ef41Sopenharmony_cithrow new EXAMPLE_KEY.RangeError(); 791cb0ef41Sopenharmony_ci``` 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ci## Documenting new errors 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ciWhenever a new static error code is added and used, corresponding documentation 841cb0ef41Sopenharmony_cifor the error code should be added to the `doc/api/errors.md` file. This will 851cb0ef41Sopenharmony_cigive users a place to go to easily look up the meaning of individual error 861cb0ef41Sopenharmony_cicodes. 871cb0ef41Sopenharmony_ci 881cb0ef41Sopenharmony_ciIn case `make lint` fails to detect the new error codes added into `errors.md`, 891cb0ef41Sopenharmony_cithe markdown linting cache must be cleaned with `make lint-md-clean`. 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci## Testing new errors 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ciWhen adding a new error, corresponding test(s) for the error message 941cb0ef41Sopenharmony_ciformatting may also be required. If the message for the error is a 951cb0ef41Sopenharmony_ciconstant string then no test is required for the error message formatting 961cb0ef41Sopenharmony_cias we can trust the error helper implementation. An example of this kind of 971cb0ef41Sopenharmony_cierror would be: 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci```js 1001cb0ef41Sopenharmony_ciE('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound'); 1011cb0ef41Sopenharmony_ci``` 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ciIf the error message is not a constant string then tests to validate 1041cb0ef41Sopenharmony_cithe formatting of the message based on the parameters used when 1051cb0ef41Sopenharmony_cicreating the error should be added to 1061cb0ef41Sopenharmony_ci`test/parallel/test-internal-errors.js`. These tests should validate 1071cb0ef41Sopenharmony_ciall of the different ways parameters can be used to generate the final 1081cb0ef41Sopenharmony_cimessage string. A simple example is: 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci```js 1111cb0ef41Sopenharmony_ci// Test ERR_TLS_CERT_ALTNAME_INVALID 1121cb0ef41Sopenharmony_ciassert.strictEqual( 1131cb0ef41Sopenharmony_ci errors.message('ERR_TLS_CERT_ALTNAME_INVALID', ['altname']), 1141cb0ef41Sopenharmony_ci 'Hostname/IP does not match certificate\'s altnames: altname'); 1151cb0ef41Sopenharmony_ci``` 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciIn addition, there should also be tests which validate the use of the 1181cb0ef41Sopenharmony_cierror based on where it is used in the codebase. If the error message is 1191cb0ef41Sopenharmony_cistatic, these tests should only validate that the expected code is received 1201cb0ef41Sopenharmony_ciand NOT validate the message. This will reduce the amount of test change 1211cb0ef41Sopenharmony_cirequired when the message for an error changes. 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci```js 1241cb0ef41Sopenharmony_ciassert.throws(() => { 1251cb0ef41Sopenharmony_ci socket.bind(); 1261cb0ef41Sopenharmony_ci}, common.expectsError({ 1271cb0ef41Sopenharmony_ci code: 'ERR_SOCKET_ALREADY_BOUND', 1281cb0ef41Sopenharmony_ci type: Error, 1291cb0ef41Sopenharmony_ci})); 1301cb0ef41Sopenharmony_ci``` 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ciAvoid changing the format of the message after the error has been created. 1331cb0ef41Sopenharmony_ciIf it does make sense to do this for some reason, then additional tests 1341cb0ef41Sopenharmony_civalidating the formatting of the error message for those cases will 1351cb0ef41Sopenharmony_cilikely be required. 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci## API 1381cb0ef41Sopenharmony_ci 1391cb0ef41Sopenharmony_ci### Object: errors.codes 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ciExposes all internal error classes to be used by Node.js APIs. 1421cb0ef41Sopenharmony_ci 1431cb0ef41Sopenharmony_ci### Method: errors.message(key, args) 1441cb0ef41Sopenharmony_ci 1451cb0ef41Sopenharmony_ci* `key` {string} The static error identifier 1461cb0ef41Sopenharmony_ci* `args` {Array} Zero or more optional arguments passed as an Array 1471cb0ef41Sopenharmony_ci* Returns: {string} 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ciReturns the formatted error message string for the given `key`. 150