Skip to content

Commit 5a3da7b

Browse files
author
Aviv Keller
authored
tools: enforce errors to not be documented in legacy section
PR-URL: #55218 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 78f421d commit 5a3da7b

File tree

3 files changed

+128
-83
lines changed

3 files changed

+128
-83
lines changed

doc/api/errors.md

+57-57
Original file line numberDiff line numberDiff line change
@@ -2325,6 +2325,17 @@ compiled with ICU support.
23252325

23262326
A non-context-aware native addon was loaded in a process that disallows them.
23272327

2328+
<a id="ERR_OPERATION_FAILED"></a>
2329+
2330+
### `ERR_OPERATION_FAILED`
2331+
2332+
<!-- YAML
2333+
added: v15.0.0
2334+
-->
2335+
2336+
An operation failed. This is typically used to signal the general failure
2337+
of an asynchronous operation.
2338+
23282339
<a id="ERR_OUT_OF_RANGE"></a>
23292340

23302341
### `ERR_OUT_OF_RANGE`
@@ -2407,6 +2418,42 @@ Accessing `Object.prototype.__proto__` has been forbidden using
24072418
[`Object.setPrototypeOf`][] should be used to get and set the prototype of an
24082419
object.
24092420

2421+
<a id="ERR_QUIC_CONNECTION_FAILED"></a>
2422+
2423+
### `ERR_QUIC_CONNECTION_FAILED`
2424+
2425+
<!-- YAML
2426+
added: REPLACEME
2427+
-->
2428+
2429+
> Stability: 1 - Experimental
2430+
2431+
Establishing a QUIC connection failed.
2432+
2433+
<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>
2434+
2435+
### `ERR_QUIC_ENDPOINT_CLOSED`
2436+
2437+
<!-- YAML
2438+
added: REPLACEME
2439+
-->
2440+
2441+
> Stability: 1 - Experimental
2442+
2443+
A QUIC Endpoint closed with an error.
2444+
2445+
<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>
2446+
2447+
### `ERR_QUIC_OPEN_STREAM_FAILED`
2448+
2449+
<!-- YAML
2450+
added: REPLACEME
2451+
-->
2452+
2453+
> Stability: 1 - Experimental
2454+
2455+
Opening a QUIC stream failed.
2456+
24102457
<a id="ERR_REQUIRE_CYCLE_MODULE"></a>
24112458

24122459
### `ERR_REQUIRE_CYCLE_MODULE`
@@ -2990,6 +3037,16 @@ try {
29903037
}
29913038
```
29923039

3040+
<a id="ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING"></a>
3041+
3042+
### `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`
3043+
3044+
<!-- YAML
3045+
added: v22.6.0
3046+
-->
3047+
3048+
Type stripping is not supported for files descendent of a `node_modules` directory.
3049+
29933050
<a id="ERR_USE_AFTER_CLOSE"></a>
29943051

29953052
### `ERR_USE_AFTER_CLOSE`
@@ -3636,17 +3693,6 @@ error indicates that the idle loop has failed to stop.
36363693
A Node.js API was called in an unsupported manner, such as
36373694
`Buffer.write(string, encoding, offset[, length])`.
36383695

3639-
<a id="ERR_OPERATION_FAILED"></a>
3640-
3641-
### `ERR_OPERATION_FAILED`
3642-
3643-
<!-- YAML
3644-
added: v15.0.0
3645-
-->
3646-
3647-
An operation failed. This is typically used to signal the general failure
3648-
of an asynchronous operation.
3649-
36503696
<a id="ERR_OUTOFMEMORY"></a>
36513697

36523698
### `ERR_OUTOFMEMORY`
@@ -3670,42 +3716,6 @@ removed: v10.0.0
36703716

36713717
The `node:repl` module was unable to parse data from the REPL history file.
36723718

3673-
<a id="ERR_QUIC_CONNECTION_FAILED"></a>
3674-
3675-
### `ERR_QUIC_CONNECTION_FAILED`
3676-
3677-
<!-- YAML
3678-
added: REPLACEME
3679-
-->
3680-
3681-
> Stability: 1 - Experimental
3682-
3683-
Establishing a QUIC connection failed.
3684-
3685-
<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>
3686-
3687-
### `ERR_QUIC_ENDPOINT_CLOSED`
3688-
3689-
<!-- YAML
3690-
added: REPLACEME
3691-
-->
3692-
3693-
> Stability: 1 - Experimental
3694-
3695-
A QUIC Endpoint closed with an error.
3696-
3697-
<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>
3698-
3699-
### `ERR_QUIC_OPEN_STREAM_FAILED`
3700-
3701-
<!-- YAML
3702-
added: REPLACEME
3703-
-->
3704-
3705-
> Stability: 1 - Experimental
3706-
3707-
Opening a QUIC stream failed.
3708-
37093719
<a id="ERR_SOCKET_CANNOT_SEND"></a>
37103720

37113721
### `ERR_SOCKET_CANNOT_SEND`
@@ -4097,16 +4107,6 @@ The public key in the certificate SubjectPublicKeyInfo could not be read.
40974107

40984108
An error occurred trying to allocate memory. This should never happen.
40994109

4100-
<a id="ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING"></a>
4101-
4102-
#### `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`
4103-
4104-
<!-- YAML
4105-
added: v22.6.0
4106-
-->
4107-
4108-
Type stripping is not supported for files descendent of a `node_modules` directory.
4109-
41104110
[ES Module]: esm.md
41114111
[ICU]: intl.md#internationalization-support
41124112
[JSON Web Key Elliptic Curve Registry]: https://www.iana.org/assignments/jose/jose.xhtml#web-key-elliptic-curve

test/parallel/test-eslint-documented-errors.js

-5
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,6 @@ new RuleTester().run('documented-errors', rule, {
2727
message: `"${invalidCode}" is not documented in doc/api/errors.md`,
2828
line: 2
2929
},
30-
{
31-
message:
32-
`doc/api/errors.md does not have an anchor for "${invalidCode}"`,
33-
line: 2
34-
},
3530
]
3631
},
3732
]

tools/eslint-rules/documented-errors.js

+71-21
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,85 @@ const fs = require('fs');
44
const path = require('path');
55
const { isDefiningError } = require('./rules-utils.js');
66

7-
const doc = fs.readFileSync(path.resolve(__dirname, '../../doc/api/errors.md'),
8-
'utf8');
7+
// Load the errors documentation file once
8+
const docPath = path.resolve(__dirname, '../../doc/api/errors.md');
9+
const doc = fs.readFileSync(docPath, 'utf8');
910

10-
function isInDoc(code) {
11-
return doc.includes(`### \`${code}\``);
12-
}
11+
// Helper function to parse errors documentation and return a Map
12+
function getErrorsInDoc() {
13+
const lines = doc.split('\n');
14+
let currentHeader;
15+
const errors = new Map();
16+
const codePattern = /^### `([^`]+)`$/;
17+
const anchorPattern = /^<a id="([^"]+)"><\/a>$/;
1318

14-
function includesAnchor(code) {
15-
return doc.includes(`<a id="${code}"></a>`);
16-
}
19+
function parse(line, legacy) {
20+
const error = { legacy };
21+
let code;
22+
23+
const codeMatch = line.match(codePattern);
24+
if (codeMatch) {
25+
error.header = true;
26+
code = codeMatch[1];
27+
}
28+
29+
const anchorMatch = line.match(anchorPattern);
30+
if (anchorMatch) {
31+
error.anchor = true;
32+
code ??= anchorMatch[1];
33+
}
34+
35+
if (!code) return;
36+
37+
// If the code already exists in the Map, merge the new error data
38+
errors.set(code, {
39+
...errors.get(code),
40+
...error,
41+
});
42+
}
43+
44+
for (const line of lines) {
45+
if (line.startsWith('## ')) currentHeader = line.substring(3);
46+
if (currentHeader === 'Node.js error codes') parse(line, false);
47+
if (currentHeader === 'Legacy Node.js error codes') parse(line, true);
48+
}
1749

18-
function errorForNode(node) {
19-
return node.expression.arguments[0].value;
50+
return errors;
2051
}
2152

53+
// Main rule export
2254
module.exports = {
23-
create: function(context) {
55+
create(context) {
56+
const errors = getErrorsInDoc();
2457
return {
25-
ExpressionStatement: function(node) {
26-
if (!isDefiningError(node) || !errorForNode(node)) return;
27-
const code = errorForNode(node);
28-
if (!isInDoc(code)) {
29-
const message = `"${code}" is not documented in doc/api/errors.md`;
30-
context.report({ node, message });
58+
ExpressionStatement(node) {
59+
if (!isDefiningError(node)) return;
60+
61+
const code = node.expression.arguments?.[0]?.value;
62+
if (!code) return;
63+
64+
const err = errors.get(code); // Use Map's get method to retrieve the error
65+
66+
if (!err || !err.header) {
67+
context.report({
68+
node,
69+
message: `"${code}" is not documented in doc/api/errors.md`,
70+
});
71+
if (!err) return;
3172
}
32-
if (!includesAnchor(code)) {
33-
const message =
34-
`doc/api/errors.md does not have an anchor for "${code}"`;
35-
context.report({ node, message });
73+
74+
if (!err.anchor) {
75+
context.report({
76+
node,
77+
message: `doc/api/errors.md does not have an anchor for "${code}"`,
78+
});
79+
}
80+
81+
if (err.legacy) {
82+
context.report({
83+
node,
84+
message: `"${code}" is marked as legacy, yet it is used in lib/.`,
85+
});
3686
}
3787
},
3888
};

0 commit comments

Comments
 (0)