diff --git a/doc/api/errors.md b/doc/api/errors.md index 4a20e14306fe53..753f84f7c56f4b 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -643,11 +643,36 @@ Used when an invalid value for the `format` argument has been passed to the Used when an invalid crypto engine identifier is passed to [`require('crypto').setEngine()`][]. + +### ERR_CRYPTO_HASH_DIGEST_NO_UTF16 + +Used when the UTF-16 encoding is used with [`hash.digest()`][]. While the +`hash.digest()` method does allow an `encoding` argument to be passed in, +causing the method to return a string rather than a `Buffer`, the UTF-16 +encoding (e.g. `ucs` or `utf16le`) is not supported. + + +### ERR_CRYPTO_HASH_FINALIZED + +Used when [`hash.digest()`][] is called multiple times. The `hash.digest()` +method must be called no more than one time per instance of a `Hash` object. + + +### ERR_CRYPTO_HASH_UPDATE_FAILED + +Used when [`hash.update()`][] fails for any reason. This should rarely, if +ever, happen. + ### ERR_CRYPTO_INVALID_DIGEST Used when an invalid [crypto digest algorithm][] is specified. + +### ERR_CRYPTO_SIGN_KEY_REQUIRED + +Used when a signing `key` is not provided to the [`sign.sign()`][] method. + ### ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH @@ -1137,6 +1162,20 @@ for strict compliance with the API specification (which in some cases may accept `func(undefined)` and `func()` are treated identically, and the [`ERR_INVALID_ARG_TYPE`][] error code may be used instead. + +### ERR_MISSING_MODULE + +> Stability: 1 - Experimental + +Used when an [ES6 module][] cannot be resolved. + + +### ERR_MODULE_RESOLUTION_LEGACY + +> Stability: 1 - Experimental + +Used when a failure occurs resolving imports in an [ES6 module][]. + ### ERR_MULTIPLE_CALLBACK @@ -1181,16 +1220,42 @@ For example: `Buffer.write(string, encoding, offset[, length])` Used generically to identify that an operation caused an out of memory condition. + +### ERR_OUT_OF_RANGE + +Used generically when an input argument value values outside an acceptable +range. + ### ERR_PARSE_HISTORY_DATA Used by the `REPL` module when it cannot parse data from the REPL history file. + +### ERR_REQUIRE_ESM + +> Stability: 1 - Experimental + +Used when an attempt is made to `require()` an [ES6 module][]. + + +### ERR_SERVER_ALREADY_LISTEN + +Used when the [`server.listen()`][] method is called while a `net.Server` is +already listening. This applies to all instances of `net.Server`, including +HTTP, HTTPS, and HTTP/2 Server instances. + ### ERR_SOCKET_ALREADY_BOUND Used when an attempt is made to bind a socket that has already been bound. + +### ERR_SOCKET_BAD_BUFFER_SIZE + +Used when an invalid (negative) size is passed for either the `recvBufferSize` +or `sendBufferSize` options in [`dgram.createSocket()`][]. + ### ERR_SOCKET_BAD_PORT @@ -1203,6 +1268,12 @@ value. Used when an API function expecting a socket type (`udp4` or `udp6`) receives an invalid value. + +### ERR_SOCKET_BUFFER_SIZE + +Used when using [`dgram.createSocket()`][] and the size of the receive or send +`Buffer` cannot be determined. + ### ERR_SOCKET_CANNOT_SEND @@ -1309,6 +1380,21 @@ is emitted by an `EventEmitter` but an `'error'` handler is not registered). Used when an invalid or unknown encoding option is passed to an API. + +### ERR_UNKNOWN_FILE_EXTENSION + +> Stability: 1 - Experimental + +Used when attempting to load a module with an unknown or unsupported file +extension. + + +### ERR_UNKNOWN_MODULE_FORMAT + +> Stability: 1 - Experimental + +Used when attempting to load a module with an unknown or unsupported format. + ### ERR_UNKNOWN_SIGNAL @@ -1355,7 +1441,11 @@ Used when an attempt is made to use a `zlib` object after it has already been closed. [`crypto.timingSafeEqual()`]: crypto.html#crypto_crypto_timingsafeequal_a_b +[`dgram.createSocket()`]: dgram.html#dgram_dgram_createsocket_options_callback [`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE +[`hash.digest()`]: crypto.html#crypto_hash_digest_encoding +[`hash.update()`]: crypto.html#crypto_hash_update_data_inputencoding +[`sign.sign()`]: crypto.html#crypto_sign_sign_privatekey_outputformat [`subprocess.kill()`]: child_process.html#child_process_subprocess_kill_signal [`subprocess.send()`]: child_process.html#child_process_subprocess_send_message_sendhandle_options_callback [`fs.readFileSync`]: fs.html#fs_fs_readfilesync_path_options @@ -1371,6 +1461,8 @@ closed. [`process.on('uncaughtException')`]: process.html#process_event_uncaughtexception [`process.send()`]: process.html#process_process_send_message_sendhandle_options_callback [`require('crypto').setEngine()`]: crypto.html#crypto_crypto_setengine_engine_flags +[`server.listen()`]: net.html#net_server_listen +[ES6 module]: esm.html [Node.js Error Codes]: #nodejs-error-codes [V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API [WHATWG URL API]: url.html#url_the_whatwg_url_api diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 48eb6b89356ac8..5ac0fb9a5457f8 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1,3 +1,4 @@ +/* eslint documented-errors: "error" */ /* eslint alphabetize-errors: "error" */ 'use strict'; diff --git a/test/parallel/test-eslint-documented-errors.js b/test/parallel/test-eslint-documented-errors.js new file mode 100644 index 00000000000000..94e81ff3abaecc --- /dev/null +++ b/test/parallel/test-eslint-documented-errors.js @@ -0,0 +1,34 @@ +'use strict'; + +require('../common'); + +const RuleTester = require('../../tools/eslint').RuleTester; +const rule = require('../../tools/eslint-rules/documented-errors'); + +const invalidCode = 'UNDOCUMENTED ERROR CODE'; + +new RuleTester().run('documented-errors', rule, { + valid: [ + ` + E('ERR_ASSERTION', 'foo'); + ` + ], + invalid: [ + { + code: ` + E('${invalidCode}', 'bar'); + `, + errors: [ + { + message: `"${invalidCode}" is not documented in doc/api/errors.md`, + line: 2 + }, + { + message: + `doc/api/errors.md does not have an anchor for "${invalidCode}"`, + line: 2 + } + ] + } + ] +}); diff --git a/tools/eslint-rules/documented-errors.js b/tools/eslint-rules/documented-errors.js new file mode 100644 index 00000000000000..471452d67a04f2 --- /dev/null +++ b/tools/eslint-rules/documented-errors.js @@ -0,0 +1,46 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +const doc = fs.readFileSync(path.resolve(__dirname, '../../doc/api/errors.md'), + 'utf8'); + +function isInDoc(code) { + return doc.match(`### ${code}`) != null; +} + +function includesAnchor(code) { + return doc.match(``) != null; +} + +function errorForNode(node) { + return node.expression.arguments[0].value; +} + +function isDefiningError(node) { + return node.expression && + node.expression.type === 'CallExpression' && + node.expression.callee && + node.expression.callee.name === 'E'; +} + +module.exports = { + create: function(context) { + return { + ExpressionStatement: function(node) { + if (!isDefiningError(node)) return; + const code = errorForNode(node); + if (!isInDoc(code)) { + const message = `"${code}" is not documented in doc/api/errors.md`; + context.report({ node, message }); + } + if (!includesAnchor(code)) { + const message = + `doc/api/errors.md does not have an anchor for "${code}"`; + context.report({ node, message }); + } + } + }; + } +};