2017-10-24 19:57:21 +02:00
|
|
|
'use strict';
|
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
const assert = require('assert');
|
2017-10-24 19:57:21 +02:00
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
2018-02-18 20:19:20 +01:00
|
|
|
const { isDefiningError } = require('./rules-utils.js');
|
2017-10-24 19:57:21 +02:00
|
|
|
|
2024-10-08 18:59:53 +02:00
|
|
|
// Load the errors documentation file once
|
|
|
|
const docPath = path.resolve(__dirname, '../../doc/api/errors.md');
|
|
|
|
const doc = fs.readFileSync(docPath, 'utf8');
|
2017-10-24 19:57:21 +02:00
|
|
|
|
2024-10-08 18:59:53 +02:00
|
|
|
// Helper function to parse errors documentation and return a Map
|
|
|
|
function getErrorsInDoc() {
|
|
|
|
const lines = doc.split('\n');
|
|
|
|
let currentHeader;
|
2024-10-10 19:18:20 +02:00
|
|
|
const errors = new Set();
|
|
|
|
const legacyErrors = new Set();
|
2024-10-08 18:59:53 +02:00
|
|
|
const codePattern = /^### `([^`]+)`$/;
|
|
|
|
const anchorPattern = /^<a id="([^"]+)"><\/a>$/;
|
2017-10-24 19:57:21 +02:00
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
let previousAnchor;
|
2024-10-08 18:59:53 +02:00
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
function parse(line, legacy, lineNumber) {
|
|
|
|
const anchorMatch = anchorPattern.exec(line);
|
2024-10-08 18:59:53 +02:00
|
|
|
if (anchorMatch) {
|
2024-10-10 19:18:20 +02:00
|
|
|
const code = anchorMatch[1];
|
|
|
|
if (previousAnchor != null && previousAnchor > code) {
|
|
|
|
throw new Error(`Unordered error anchor in ${docPath}:${lineNumber}`, { cause: `${previousAnchor} ≤ ${code}` });
|
|
|
|
}
|
|
|
|
previousAnchor = code;
|
|
|
|
return;
|
2024-10-08 18:59:53 +02:00
|
|
|
}
|
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
const codeMatch = codePattern.exec(line);
|
|
|
|
if (codeMatch == null) return;
|
2024-10-08 18:59:53 +02:00
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
const code = codeMatch[1];
|
|
|
|
if (previousAnchor == null) {
|
|
|
|
throw new Error(`Missing error anchor in ${docPath}:${lineNumber}`, { cause: code });
|
|
|
|
}
|
|
|
|
assert.strictEqual(code, previousAnchor, `Error anchor do not match with error code in ${docPath}:${lineNumber}`);
|
|
|
|
|
|
|
|
if (legacy && errors.has(code)) {
|
|
|
|
throw new Error(`Error is documented both as legacy and non-legacy in ${docPath}:${lineNumber}`, { cause: code });
|
|
|
|
}
|
|
|
|
(legacy ? legacyErrors : errors).add(code);
|
2024-10-08 18:59:53 +02:00
|
|
|
}
|
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
let lineNumber = 0;
|
2024-10-08 18:59:53 +02:00
|
|
|
for (const line of lines) {
|
2024-10-10 19:18:20 +02:00
|
|
|
lineNumber++;
|
2024-10-08 18:59:53 +02:00
|
|
|
if (line.startsWith('## ')) currentHeader = line.substring(3);
|
2024-10-10 19:18:20 +02:00
|
|
|
if (currentHeader === 'Node.js error codes') parse(line, false, lineNumber);
|
|
|
|
if (line === '## Legacy Node.js error codes') previousAnchor = null;
|
|
|
|
if (currentHeader === 'Legacy Node.js error codes') parse(line, true, lineNumber);
|
2024-10-08 18:59:53 +02:00
|
|
|
}
|
2017-10-24 19:57:21 +02:00
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
return { errors, legacyErrors };
|
2017-10-24 19:57:21 +02:00
|
|
|
}
|
|
|
|
|
2024-10-08 18:59:53 +02:00
|
|
|
// Main rule export
|
2017-10-24 19:57:21 +02:00
|
|
|
module.exports = {
|
2024-10-08 18:59:53 +02:00
|
|
|
create(context) {
|
2024-10-10 19:18:20 +02:00
|
|
|
const { errors, legacyErrors } = getErrorsInDoc();
|
2017-10-24 19:57:21 +02:00
|
|
|
return {
|
2024-10-08 18:59:53 +02:00
|
|
|
ExpressionStatement(node) {
|
|
|
|
if (!isDefiningError(node)) return;
|
|
|
|
|
|
|
|
const code = node.expression.arguments?.[0]?.value;
|
|
|
|
if (!code) return;
|
|
|
|
|
2024-10-10 19:18:20 +02:00
|
|
|
if (legacyErrors.has(code)) {
|
2024-10-08 18:59:53 +02:00
|
|
|
context.report({
|
|
|
|
node,
|
2024-10-10 19:18:20 +02:00
|
|
|
message: `"${code}" is marked as legacy, yet it is used in lib/.`,
|
2024-10-08 18:59:53 +02:00
|
|
|
});
|
2024-10-10 19:18:20 +02:00
|
|
|
} else if (!errors.has(code)) {
|
2024-10-08 18:59:53 +02:00
|
|
|
context.report({
|
|
|
|
node,
|
2024-10-10 19:18:20 +02:00
|
|
|
message: `"${code}" is not documented in doc/api/errors.md`,
|
2024-10-08 18:59:53 +02:00
|
|
|
});
|
2017-10-24 19:57:21 +02:00
|
|
|
}
|
2022-12-18 17:39:39 +01:00
|
|
|
},
|
2017-10-24 19:57:21 +02:00
|
|
|
};
|
2022-12-18 17:39:39 +01:00
|
|
|
},
|
2017-10-24 19:57:21 +02:00
|
|
|
};
|