2017-10-24 10:57:21 -07:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
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 10:57:21 -07:00
|
|
|
|
2024-10-08 12:59:53 -04: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 10:57:21 -07:00
|
|
|
|
2024-10-08 12:59:53 -04:00
|
|
|
// 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>$/;
|
2017-10-24 10:57:21 -07:00
|
|
|
|
2024-10-08 12:59:53 -04:00
|
|
|
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);
|
|
|
|
}
|
2017-10-24 10:57:21 -07:00
|
|
|
|
2024-10-08 12:59:53 -04:00
|
|
|
return errors;
|
2017-10-24 10:57:21 -07:00
|
|
|
}
|
|
|
|
|
2024-10-08 12:59:53 -04:00
|
|
|
// Main rule export
|
2017-10-24 10:57:21 -07:00
|
|
|
module.exports = {
|
2024-10-08 12:59:53 -04:00
|
|
|
create(context) {
|
|
|
|
const errors = getErrorsInDoc();
|
2017-10-24 10:57:21 -07:00
|
|
|
return {
|
2024-10-08 12:59:53 -04:00
|
|
|
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;
|
2017-10-24 10:57:21 -07:00
|
|
|
}
|
2024-10-08 12:59:53 -04:00
|
|
|
|
|
|
|
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/.`,
|
|
|
|
});
|
2017-10-24 10:57:21 -07:00
|
|
|
}
|
2022-12-18 17:39:39 +01:00
|
|
|
},
|
2017-10-24 10:57:21 -07:00
|
|
|
};
|
2022-12-18 17:39:39 +01:00
|
|
|
},
|
2017-10-24 10:57:21 -07:00
|
|
|
};
|