Skip to content

Commit

Permalink
tools: enforce errors to not be documented in legacy section
Browse files Browse the repository at this point in the history
PR-URL: nodejs#55218
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
  • Loading branch information
RedYetiDev authored Oct 8, 2024
1 parent 78f421d commit 5a3da7b
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 83 deletions.
114 changes: 57 additions & 57 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,17 @@ compiled with ICU support.

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

<a id="ERR_OPERATION_FAILED"></a>

### `ERR_OPERATION_FAILED`

<!-- YAML
added: v15.0.0
-->

An operation failed. This is typically used to signal the general failure
of an asynchronous operation.

<a id="ERR_OUT_OF_RANGE"></a>

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

<a id="ERR_QUIC_CONNECTION_FAILED"></a>

### `ERR_QUIC_CONNECTION_FAILED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Establishing a QUIC connection failed.

<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>

### `ERR_QUIC_ENDPOINT_CLOSED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
A QUIC Endpoint closed with an error.

<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>

### `ERR_QUIC_OPEN_STREAM_FAILED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Opening a QUIC stream failed.

<a id="ERR_REQUIRE_CYCLE_MODULE"></a>

### `ERR_REQUIRE_CYCLE_MODULE`
Expand Down Expand Up @@ -2990,6 +3037,16 @@ try {
}
```

<a id="ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING"></a>

### `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`

<!-- YAML
added: v22.6.0
-->

Type stripping is not supported for files descendent of a `node_modules` directory.

<a id="ERR_USE_AFTER_CLOSE"></a>

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

<a id="ERR_OPERATION_FAILED"></a>

### `ERR_OPERATION_FAILED`

<!-- YAML
added: v15.0.0
-->

An operation failed. This is typically used to signal the general failure
of an asynchronous operation.

<a id="ERR_OUTOFMEMORY"></a>

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

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

<a id="ERR_QUIC_CONNECTION_FAILED"></a>

### `ERR_QUIC_CONNECTION_FAILED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Establishing a QUIC connection failed.

<a id="ERR_QUIC_ENDPOINT_CLOSED"></a>

### `ERR_QUIC_ENDPOINT_CLOSED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
A QUIC Endpoint closed with an error.

<a id="ERR_QUIC_OPEN_STREAM_FAILED"></a>

### `ERR_QUIC_OPEN_STREAM_FAILED`

<!-- YAML
added: REPLACEME
-->

> Stability: 1 - Experimental
Opening a QUIC stream failed.

<a id="ERR_SOCKET_CANNOT_SEND"></a>

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

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

<a id="ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING"></a>

#### `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`

<!-- YAML
added: v22.6.0
-->

Type stripping is not supported for files descendent of a `node_modules` directory.

[ES Module]: esm.md
[ICU]: intl.md#internationalization-support
[JSON Web Key Elliptic Curve Registry]: https://www.iana.org/assignments/jose/jose.xhtml#web-key-elliptic-curve
Expand Down
5 changes: 0 additions & 5 deletions test/parallel/test-eslint-documented-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ new RuleTester().run('documented-errors', rule, {
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
},
]
},
]
Expand Down
92 changes: 71 additions & 21 deletions tools/eslint-rules/documented-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,85 @@ const fs = require('fs');
const path = require('path');
const { isDefiningError } = require('./rules-utils.js');

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

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

function includesAnchor(code) {
return doc.includes(`<a id="${code}"></a>`);
}
function parse(line, legacy) {
const error = { legacy };
let code;

const codeMatch = line.match(codePattern);
if (codeMatch) {
error.header = true;
code = codeMatch[1];
}

const anchorMatch = line.match(anchorPattern);
if (anchorMatch) {
error.anchor = true;
code ??= anchorMatch[1];
}

if (!code) return;

// If the code already exists in the Map, merge the new error data
errors.set(code, {
...errors.get(code),
...error,
});
}

for (const line of lines) {
if (line.startsWith('## ')) currentHeader = line.substring(3);
if (currentHeader === 'Node.js error codes') parse(line, false);
if (currentHeader === 'Legacy Node.js error codes') parse(line, true);
}

function errorForNode(node) {
return node.expression.arguments[0].value;
return errors;
}

// Main rule export
module.exports = {
create: function(context) {
create(context) {
const errors = getErrorsInDoc();
return {
ExpressionStatement: function(node) {
if (!isDefiningError(node) || !errorForNode(node)) return;
const code = errorForNode(node);
if (!isInDoc(code)) {
const message = `"${code}" is not documented in doc/api/errors.md`;
context.report({ node, message });
ExpressionStatement(node) {
if (!isDefiningError(node)) return;

const code = node.expression.arguments?.[0]?.value;
if (!code) return;

const err = errors.get(code); // Use Map's get method to retrieve the error

if (!err || !err.header) {
context.report({
node,
message: `"${code}" is not documented in doc/api/errors.md`,
});
if (!err) return;
}
if (!includesAnchor(code)) {
const message =
`doc/api/errors.md does not have an anchor for "${code}"`;
context.report({ node, message });

if (!err.anchor) {
context.report({
node,
message: `doc/api/errors.md does not have an anchor for "${code}"`,
});
}

if (err.legacy) {
context.report({
node,
message: `"${code}" is marked as legacy, yet it is used in lib/.`,
});
}
},
};
Expand Down

0 comments on commit 5a3da7b

Please sign in to comment.