Skip to content

Commit d51e5a8

Browse files
Aviv Kelleraduh95
Aviv Keller
authored andcommitted
tools: enforce errors to not be documented in legacy section
PR-URL: #55218 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 08b5e6c commit d51e5a8

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
@@ -2338,6 +2338,17 @@ compiled with ICU support.
23382338

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

2341+
<a id="ERR_OPERATION_FAILED"></a>
2342+
2343+
### `ERR_OPERATION_FAILED`
2344+
2345+
<!-- YAML
2346+
added: v15.0.0
2347+
-->
2348+
2349+
An operation failed. This is typically used to signal the general failure
2350+
of an asynchronous operation.
2351+
23412352
<a id="ERR_OUT_OF_RANGE"></a>
23422353

23432354
### `ERR_OUT_OF_RANGE`
@@ -2420,6 +2431,42 @@ Accessing `Object.prototype.__proto__` has been forbidden using
24202431
[`Object.setPrototypeOf`][] should be used to get and set the prototype of an
24212432
object.
24222433

2434+
<a id="ERR_QUIC_CONNECTION_FAILED"></a>
2435+
2436+
### `ERR_QUIC_CONNECTION_FAILED`
2437+
2438+
<!-- YAML
2439+
added: REPLACEME
2440+
-->
2441+
2442+
> Stability: 1 - Experimental
2443+
2444+
Establishing a QUIC connection failed.
2445+
2446+
<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>
2447+
2448+
### `ERR_QUIC_ENDPOINT_CLOSED`
2449+
2450+
<!-- YAML
2451+
added: REPLACEME
2452+
-->
2453+
2454+
> Stability: 1 - Experimental
2455+
2456+
A QUIC Endpoint closed with an error.
2457+
2458+
<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>
2459+
2460+
### `ERR_QUIC_OPEN_STREAM_FAILED`
2461+
2462+
<!-- YAML
2463+
added: REPLACEME
2464+
-->
2465+
2466+
> Stability: 1 - Experimental
2467+
2468+
Opening a QUIC stream failed.
2469+
24232470
<a id="ERR_REQUIRE_CYCLE_MODULE"></a>
24242471

24252472
### `ERR_REQUIRE_CYCLE_MODULE`
@@ -2989,6 +3036,16 @@ try {
29893036
}
29903037
```
29913038

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

29943051
### `ERR_USE_AFTER_CLOSE`
@@ -3612,17 +3669,6 @@ error indicates that the idle loop has failed to stop.
36123669
A Node.js API was called in an unsupported manner, such as
36133670
`Buffer.write(string, encoding, offset[, length])`.
36143671

3615-
<a id="ERR_OPERATION_FAILED"></a>
3616-
3617-
### `ERR_OPERATION_FAILED`
3618-
3619-
<!-- YAML
3620-
added: v15.0.0
3621-
-->
3622-
3623-
An operation failed. This is typically used to signal the general failure
3624-
of an asynchronous operation.
3625-
36263672
<a id="ERR_OUTOFMEMORY"></a>
36273673

36283674
### `ERR_OUTOFMEMORY`
@@ -3646,42 +3692,6 @@ removed: v10.0.0
36463692

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

3649-
<a id="ERR_QUIC_CONNECTION_FAILED"></a>
3650-
3651-
### `ERR_QUIC_CONNECTION_FAILED`
3652-
3653-
<!-- YAML
3654-
added: REPLACEME
3655-
-->
3656-
3657-
> Stability: 1 - Experimental
3658-
3659-
Establishing a QUIC connection failed.
3660-
3661-
<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>
3662-
3663-
### `ERR_QUIC_ENDPOINT_CLOSED`
3664-
3665-
<!-- YAML
3666-
added: REPLACEME
3667-
-->
3668-
3669-
> Stability: 1 - Experimental
3670-
3671-
A QUIC Endpoint closed with an error.
3672-
3673-
<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>
3674-
3675-
### `ERR_QUIC_OPEN_STREAM_FAILED`
3676-
3677-
<!-- YAML
3678-
added: REPLACEME
3679-
-->
3680-
3681-
> Stability: 1 - Experimental
3682-
3683-
Opening a QUIC stream failed.
3684-
36853695
<a id="ERR_SOCKET_CANNOT_SEND"></a>
36863696

36873697
### `ERR_SOCKET_CANNOT_SEND`
@@ -4073,16 +4083,6 @@ The public key in the certificate SubjectPublicKeyInfo could not be read.
40734083

40744084
An error occurred trying to allocate memory. This should never happen.
40754085

4076-
<a id="ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING"></a>
4077-
4078-
#### `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`
4079-
4080-
<!-- YAML
4081-
added: v22.6.0
4082-
-->
4083-
4084-
Type stripping is not supported for files descendent of a `node_modules` directory.
4085-
40864086
[ES Module]: esm.md
40874087
[ICU]: intl.md#internationalization-support
40884088
[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)