eslint-plugin-reliability 3.1.9 β 3.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +2 -3
- package/src/index.js +1 -52
- package/src/lib/eslint-plugin-reliability.js +1 -6
- package/src/oxlint.js +1 -3
- package/src/rules/error-handling/error-message.js +1 -131
- package/src/rules/error-handling/no-missing-error-context.js +1 -180
- package/src/rules/error-handling/no-silent-errors.js +1 -157
- package/src/rules/error-handling/no-unhandled-promise.js +1 -321
- package/src/rules/reliability/no-await-in-loop.js +1 -218
- package/src/rules/reliability/no-jsdoc-terminator-in-example.js +1 -109
- package/src/rules/reliability/no-missing-null-checks.js +1 -413
- package/src/rules/reliability/no-unsafe-type-narrowing.js +1 -155
- package/src/rules/reliability/require-network-timeout.js +1 -50
package/README.md
CHANGED
|
@@ -162,7 +162,7 @@ See the [ESLint Version Support Policy](../../docs/ESLINT_VERSION_SUPPORT.md)
|
|
|
162
162
|
| [no-jsdoc-terminator-in-example](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-jsdoc-terminator-in-example?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Detect `*/` sequences inside JSDoc `@example` blocks that prematurely close the JSDoc comment. | π’ | | | | π‘ | |
|
|
163
163
|
| [no-missing-error-context](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-error-context?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-missing-error-context with LLM-optimized suggestions and auto-fix capabilities. | π’ | | | | π‘ | |
|
|
164
164
|
| [no-missing-null-checks](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-missing-null-checks?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | CWE-476 | | | ESLint Rule: no-missing-null-checks with LLM-optimized suggestions and auto-fix capabilities. | π’ | | β οΈ | | π‘ | |
|
|
165
|
-
| [no-silent-errors](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-silent-errors?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-silent-errors with LLM-optimized suggestions and auto-fix capabilities. | π’ |
|
|
165
|
+
| [no-silent-errors](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-silent-errors?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-silent-errors with LLM-optimized suggestions and auto-fix capabilities. | π’ | πΌ | | | π‘ | |
|
|
166
166
|
| [no-unhandled-promise](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unhandled-promise?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | CWE-1024 | | | Disallow unhandled Promise rejections with LLM-optimized suggestions for proper async error handling. Thisβ¦ | π’ | | | | π‘ | |
|
|
167
167
|
| [no-unsafe-type-narrowing](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/no-unsafe-type-narrowing?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | ESLint Rule: no-unsafe-type-narrowing with LLM-optimized suggestions and auto-fix capabilities. | π’ | | | | π‘ | |
|
|
168
168
|
| [require-network-timeout](https://eslint.interlace.tools/docs/quality/plugin-reliability/rules/require-network-timeout?utm_source=github&utm_medium=referral&utm_campaign=eslint-plugin-reliability) | | | | Require timeout configuration for network requests. This rule is part of eslint-plugin-reliability and provβ¦ | π’ | πΌ | | | π‘ | |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-reliability",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.11",
|
|
4
4
|
"description": "ESLint plugin for runtime reliability β enforces error handling, network timeouts, null checks, and safe type narrowing.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -50,8 +50,7 @@
|
|
|
50
50
|
"node": ">=18.0.0"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"
|
|
54
|
-
"@interlace/eslint-devkit": "^1.6.1"
|
|
53
|
+
"@interlace/eslint-devkit": "^1.10.0"
|
|
55
54
|
},
|
|
56
55
|
"repository": {
|
|
57
56
|
"type": "git",
|
package/src/index.js
CHANGED
|
@@ -1,52 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.configs = exports.plugin = exports.rules = void 0;
|
|
4
|
-
const no_unhandled_promise_1 = require("./rules/error-handling/no-unhandled-promise");
|
|
5
|
-
const no_silent_errors_1 = require("./rules/error-handling/no-silent-errors");
|
|
6
|
-
const no_missing_error_context_1 = require("./rules/error-handling/no-missing-error-context");
|
|
7
|
-
const error_message_1 = require("./rules/error-handling/error-message");
|
|
8
|
-
const no_missing_null_checks_1 = require("./rules/reliability/no-missing-null-checks");
|
|
9
|
-
const no_unsafe_type_narrowing_1 = require("./rules/reliability/no-unsafe-type-narrowing");
|
|
10
|
-
const require_network_timeout_1 = require("./rules/reliability/require-network-timeout");
|
|
11
|
-
const no_await_in_loop_1 = require("./rules/reliability/no-await-in-loop");
|
|
12
|
-
const no_jsdoc_terminator_in_example_1 = require("./rules/reliability/no-jsdoc-terminator-in-example");
|
|
13
|
-
exports.rules = {
|
|
14
|
-
'no-unhandled-promise': no_unhandled_promise_1.noUnhandledPromise,
|
|
15
|
-
'no-silent-errors': no_silent_errors_1.noSilentErrors,
|
|
16
|
-
'no-missing-error-context': no_missing_error_context_1.noMissingErrorContext,
|
|
17
|
-
'error-message': error_message_1.errorMessage,
|
|
18
|
-
'no-missing-null-checks': no_missing_null_checks_1.noMissingNullChecks,
|
|
19
|
-
'no-unsafe-type-narrowing': no_unsafe_type_narrowing_1.noUnsafeTypeNarrowing,
|
|
20
|
-
'require-network-timeout': require_network_timeout_1.requireNetworkTimeout,
|
|
21
|
-
'no-await-in-loop': no_await_in_loop_1.noAwaitInLoop,
|
|
22
|
-
'no-jsdoc-terminator-in-example': no_jsdoc_terminator_in_example_1.noJsdocTerminatorInExample,
|
|
23
|
-
'error-handling/no-unhandled-promise': no_unhandled_promise_1.noUnhandledPromise,
|
|
24
|
-
'error-handling/no-silent-errors': no_silent_errors_1.noSilentErrors,
|
|
25
|
-
'error-handling/no-missing-error-context': no_missing_error_context_1.noMissingErrorContext,
|
|
26
|
-
'error-handling/error-message': error_message_1.errorMessage,
|
|
27
|
-
'reliability/no-missing-null-checks': no_missing_null_checks_1.noMissingNullChecks,
|
|
28
|
-
'reliability/no-unsafe-type-narrowing': no_unsafe_type_narrowing_1.noUnsafeTypeNarrowing,
|
|
29
|
-
'reliability/require-network-timeout': require_network_timeout_1.requireNetworkTimeout,
|
|
30
|
-
'reliability/no-await-in-loop': no_await_in_loop_1.noAwaitInLoop,
|
|
31
|
-
'reliability/no-jsdoc-terminator-in-example': no_jsdoc_terminator_in_example_1.noJsdocTerminatorInExample,
|
|
32
|
-
};
|
|
33
|
-
exports.plugin = {
|
|
34
|
-
meta: {
|
|
35
|
-
name: 'eslint-plugin-reliability',
|
|
36
|
-
version: '3.1.9',
|
|
37
|
-
},
|
|
38
|
-
rules: exports.rules,
|
|
39
|
-
};
|
|
40
|
-
exports.configs = {
|
|
41
|
-
recommended: {
|
|
42
|
-
plugins: {
|
|
43
|
-
reliability: exports.plugin,
|
|
44
|
-
},
|
|
45
|
-
rules: {
|
|
46
|
-
'reliability/no-silent-errors': 'error',
|
|
47
|
-
'reliability/no-missing-null-checks': 'warn',
|
|
48
|
-
'reliability/require-network-timeout': 'error',
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
exports.default = exports.plugin;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.configs=exports.plugin=exports.rules=void 0;exports.rules={get"no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample},get"error-handling/no-unhandled-promise"(){return require("./rules/error-handling/no-unhandled-promise").noUnhandledPromise},get"error-handling/no-silent-errors"(){return require("./rules/error-handling/no-silent-errors").noSilentErrors},get"error-handling/no-missing-error-context"(){return require("./rules/error-handling/no-missing-error-context").noMissingErrorContext},get"error-handling/error-message"(){return require("./rules/error-handling/error-message").errorMessage},get"reliability/no-missing-null-checks"(){return require("./rules/reliability/no-missing-null-checks").noMissingNullChecks},get"reliability/no-unsafe-type-narrowing"(){return require("./rules/reliability/no-unsafe-type-narrowing").noUnsafeTypeNarrowing},get"reliability/require-network-timeout"(){return require("./rules/reliability/require-network-timeout").requireNetworkTimeout},get"reliability/no-await-in-loop"(){return require("./rules/reliability/no-await-in-loop").noAwaitInLoop},get"reliability/no-jsdoc-terminator-in-example"(){return require("./rules/reliability/no-jsdoc-terminator-in-example").noJsdocTerminatorInExample}};exports.plugin={meta:{name:"eslint-plugin-reliability",version:"3.1.11"},rules:exports.rules};exports.configs={recommended:{plugins:{reliability:exports.plugin},rules:{"reliability/no-silent-errors":"error","reliability/no-missing-null-checks":"warn","reliability/require-network-timeout":"error"}}};exports.default=exports.plugin;
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.eslintPluginReliability = eslintPluginReliability;
|
|
4
|
-
function eslintPluginReliability() {
|
|
5
|
-
return 'eslint-plugin-reliability';
|
|
6
|
-
}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.eslintPluginReliability=eslintPluginReliability;function eslintPluginReliability(){return"eslint-plugin-reliability"}
|
package/src/oxlint.js
CHANGED
|
@@ -1,131 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.errorMessage = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
exports.errorMessage = (0, eslint_devkit_1.createRule)({
|
|
7
|
-
name: 'error-message',
|
|
8
|
-
meta: {
|
|
9
|
-
type: 'problem',
|
|
10
|
-
docs: {
|
|
11
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/error-message.md',
|
|
12
|
-
description: 'Enforce providing a message when creating built-in Error objects for better debugging',
|
|
13
|
-
},
|
|
14
|
-
hasSuggestions: true,
|
|
15
|
-
messages: {
|
|
16
|
-
missingErrorMessage: (0, eslint_devkit_2.formatLLMMessage)({
|
|
17
|
-
icon: eslint_devkit_2.MessageIcons.INFO,
|
|
18
|
-
issueName: 'Missing Error Message',
|
|
19
|
-
description: 'Error constructor called without message parameter',
|
|
20
|
-
severity: 'HIGH',
|
|
21
|
-
fix: 'Add descriptive error message: new Error("description")',
|
|
22
|
-
documentationLink: 'https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md',
|
|
23
|
-
}),
|
|
24
|
-
addErrorMessage: (0, eslint_devkit_2.formatLLMMessage)({
|
|
25
|
-
icon: eslint_devkit_2.MessageIcons.WARNING,
|
|
26
|
-
issueName: 'Add Error Message',
|
|
27
|
-
description: 'Add descriptive error message to constructor',
|
|
28
|
-
severity: 'HIGH',
|
|
29
|
-
fix: 'Add descriptive error message: new Error("description")',
|
|
30
|
-
documentationLink: 'https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md',
|
|
31
|
-
}),
|
|
32
|
-
},
|
|
33
|
-
schema: [
|
|
34
|
-
{
|
|
35
|
-
type: 'object',
|
|
36
|
-
properties: {
|
|
37
|
-
allowEmptyCatch: {
|
|
38
|
-
type: 'boolean',
|
|
39
|
-
default: false,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
additionalProperties: false,
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
defaultOptions: [{ allowEmptyCatch: false }],
|
|
47
|
-
create(context) {
|
|
48
|
-
const [options] = context.options;
|
|
49
|
-
const { allowEmptyCatch = false } = options || {};
|
|
50
|
-
const errorConstructors = new Set([
|
|
51
|
-
'Error',
|
|
52
|
-
'TypeError',
|
|
53
|
-
'ReferenceError',
|
|
54
|
-
'SyntaxError',
|
|
55
|
-
'RangeError',
|
|
56
|
-
'EvalError',
|
|
57
|
-
'URIError',
|
|
58
|
-
]);
|
|
59
|
-
function isErrorConstructor(name) {
|
|
60
|
-
return errorConstructors.has(name);
|
|
61
|
-
}
|
|
62
|
-
function hasMessageArgument(node) {
|
|
63
|
-
if (!node.arguments || node.arguments.length === 0) {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
const firstArg = node.arguments[0];
|
|
67
|
-
if (firstArg.type === 'Literal') {
|
|
68
|
-
return (typeof firstArg.value === 'string' && firstArg.value.trim().length > 0);
|
|
69
|
-
}
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
function isInCatchClause(node) {
|
|
73
|
-
let current = node;
|
|
74
|
-
while (current) {
|
|
75
|
-
if (current.type === 'CatchClause') {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
current = current.parent;
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
function checkErrorCreation(node) {
|
|
83
|
-
let constructorName = null;
|
|
84
|
-
if (node.type === 'NewExpression') {
|
|
85
|
-
if (node.callee.type === 'Identifier') {
|
|
86
|
-
constructorName = node.callee.name;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
else if (node.type === 'CallExpression') {
|
|
90
|
-
if (node.callee.type === 'Identifier') {
|
|
91
|
-
constructorName = node.callee.name;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (!constructorName || !isErrorConstructor(constructorName)) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (allowEmptyCatch && isInCatchClause(node)) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (!hasMessageArgument(node)) {
|
|
101
|
-
context.report({
|
|
102
|
-
node,
|
|
103
|
-
messageId: 'missingErrorMessage',
|
|
104
|
-
data: {
|
|
105
|
-
constructor: constructorName,
|
|
106
|
-
},
|
|
107
|
-
suggest: [
|
|
108
|
-
{
|
|
109
|
-
messageId: 'addErrorMessage',
|
|
110
|
-
data: { constructor: constructorName },
|
|
111
|
-
fix(fixer) {
|
|
112
|
-
if (node.arguments.length === 0) {
|
|
113
|
-
const parenStart = node.callee.range[1];
|
|
114
|
-
const parenEnd = node.range[1];
|
|
115
|
-
return fixer.replaceTextRange([parenStart, parenEnd], '("Error message")');
|
|
116
|
-
}
|
|
117
|
-
else {
|
|
118
|
-
return fixer.replaceText(node.arguments[0], '"Error message"');
|
|
119
|
-
}
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
NewExpression: checkErrorCreation,
|
|
128
|
-
CallExpression: checkErrorCreation,
|
|
129
|
-
};
|
|
130
|
-
},
|
|
131
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.errorMessage=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");exports.errorMessage=(0,eslint_devkit_1.createRule)({name:"error-message",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/error-message.md",description:"Enforce providing a message when creating built-in Error objects for better debugging"},hasSuggestions:true,messages:{missingErrorMessage:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.INFO,issueName:"Missing Error Message",description:"Error constructor called without message parameter",severity:"HIGH",fix:'Add descriptive error message: new Error("description")',documentationLink:"https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md"}),addErrorMessage:(0,eslint_devkit_2.formatLLMMessage)({icon:eslint_devkit_2.MessageIcons.WARNING,issueName:"Add Error Message",description:"Add descriptive error message to constructor",severity:"HIGH",fix:'Add descriptive error message: new Error("description")',documentationLink:"https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/error-message.md"})},schema:[{type:"object",properties:{allowEmptyCatch:{type:"boolean",default:false}},additionalProperties:false}]},defaultOptions:[{allowEmptyCatch:false}],create(context){const[options]=context.options;const{allowEmptyCatch=false}=options||{};const errorConstructors=new Set(["Error","TypeError","ReferenceError","SyntaxError","RangeError","EvalError","URIError"]);function isErrorConstructor(name){return errorConstructors.has(name)}function hasMessageArgument(node){if(!node.arguments||node.arguments.length===0){return false}const firstArg=node.arguments[0];if(firstArg.type==="Literal"){return typeof firstArg.value==="string"&&firstArg.value.trim().length>0}return true}function isInCatchClause(node){let current=node;while(current){if(current.type==="CatchClause"){return true}current=current.parent}return false}function checkErrorCreation(node){let constructorName=null;if(node.type==="NewExpression"){if(node.callee.type==="Identifier"){constructorName=node.callee.name}}else if(node.type==="CallExpression"){if(node.callee.type==="Identifier"){constructorName=node.callee.name}}if(!constructorName||!isErrorConstructor(constructorName)){return}if(allowEmptyCatch&&isInCatchClause(node)){return}if(!hasMessageArgument(node)){context.report({node,messageId:"missingErrorMessage",data:{constructor:constructorName},suggest:[{messageId:"addErrorMessage",data:{constructor:constructorName},fix(fixer){if(node.arguments.length===0){const parenStart=node.callee.range[1];const parenEnd=node.range[1];return fixer.replaceTextRange([parenStart,parenEnd],'("Error message")')}else{return fixer.replaceText(node.arguments[0],'"Error message"')}}}]})}}return{NewExpression:checkErrorCreation,CallExpression:checkErrorCreation}}});
|
|
@@ -1,180 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noMissingErrorContext = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
function hasErrorMessage(node) {
|
|
7
|
-
if (!node.argument) {
|
|
8
|
-
return false;
|
|
9
|
-
}
|
|
10
|
-
if (node.argument.type === 'Identifier' &&
|
|
11
|
-
node.argument.name !== 'undefined' &&
|
|
12
|
-
node.argument.name !== 'NaN' &&
|
|
13
|
-
node.argument.name !== 'Infinity') {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
if (node.argument.type === 'NewExpression' &&
|
|
17
|
-
node.argument.callee.type === 'Identifier' &&
|
|
18
|
-
(node.argument.callee.name === 'Error' ||
|
|
19
|
-
node.argument.callee.name.endsWith('Error'))) {
|
|
20
|
-
if (node.argument.arguments.length > 0) {
|
|
21
|
-
const firstArg = node.argument.arguments[0];
|
|
22
|
-
if (firstArg.type === 'Literal' && typeof firstArg.value === 'string') {
|
|
23
|
-
return firstArg.value.length > 0;
|
|
24
|
-
}
|
|
25
|
-
if (firstArg.type === 'TemplateLiteral') {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
if (node.argument.callee.name !== 'Error' &&
|
|
29
|
-
node.argument.callee.name.endsWith('Error')) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
if (node.argument.type === 'Literal' &&
|
|
35
|
-
typeof node.argument.value === 'string') {
|
|
36
|
-
return node.argument.value.length > 0;
|
|
37
|
-
}
|
|
38
|
-
if (node.argument.type === 'TemplateLiteral') {
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
function hasErrorStack(node) {
|
|
44
|
-
if (!node.argument) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
if (node.argument.type === 'Identifier' &&
|
|
48
|
-
node.argument.name !== 'undefined' &&
|
|
49
|
-
node.argument.name !== 'NaN' &&
|
|
50
|
-
node.argument.name !== 'Infinity') {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
if (node.argument.type === 'NewExpression' &&
|
|
54
|
-
node.argument.callee.type === 'Identifier') {
|
|
55
|
-
const calleeName = node.argument.callee.name;
|
|
56
|
-
if (calleeName === 'Error' || calleeName.endsWith('Error')) {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
exports.noMissingErrorContext = (0, eslint_devkit_2.createRule)({
|
|
63
|
-
name: 'no-missing-error-context',
|
|
64
|
-
meta: {
|
|
65
|
-
type: 'suggestion',
|
|
66
|
-
docs: {
|
|
67
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-missing-error-context.md',
|
|
68
|
-
description: 'Detects thrown errors without context',
|
|
69
|
-
},
|
|
70
|
-
hasSuggestions: true,
|
|
71
|
-
messages: {
|
|
72
|
-
missingErrorContext: (0, eslint_devkit_1.formatLLMMessage)({
|
|
73
|
-
icon: eslint_devkit_1.MessageIcons.WARNING,
|
|
74
|
-
issueName: 'Missing error context',
|
|
75
|
-
description: 'Thrown error missing {{missing}}',
|
|
76
|
-
severity: 'MEDIUM',
|
|
77
|
-
fix: 'Add error message and use Error class for stack trace',
|
|
78
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-1128/',
|
|
79
|
-
}),
|
|
80
|
-
addErrorMessage: (0, eslint_devkit_1.formatLLMMessage)({
|
|
81
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
82
|
-
issueName: 'Add Error Message',
|
|
83
|
-
description: 'Add descriptive error message',
|
|
84
|
-
severity: 'LOW',
|
|
85
|
-
fix: 'throw new Error("descriptive message")',
|
|
86
|
-
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error',
|
|
87
|
-
}),
|
|
88
|
-
addErrorStack: (0, eslint_devkit_1.formatLLMMessage)({
|
|
89
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
90
|
-
issueName: 'Use Error Class',
|
|
91
|
-
description: 'Use Error class for stack trace',
|
|
92
|
-
severity: 'LOW',
|
|
93
|
-
fix: 'throw new Error(message) instead of throw message',
|
|
94
|
-
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error',
|
|
95
|
-
}),
|
|
96
|
-
useErrorClass: (0, eslint_devkit_1.formatLLMMessage)({
|
|
97
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
98
|
-
issueName: 'Use Specific Error',
|
|
99
|
-
description: 'Use specific error class',
|
|
100
|
-
severity: 'LOW',
|
|
101
|
-
fix: 'throw new TypeError("message") or throw new RangeError("message")',
|
|
102
|
-
documentationLink: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError',
|
|
103
|
-
}),
|
|
104
|
-
},
|
|
105
|
-
schema: [
|
|
106
|
-
{
|
|
107
|
-
type: 'object',
|
|
108
|
-
properties: {
|
|
109
|
-
requireMessage: {
|
|
110
|
-
type: 'boolean',
|
|
111
|
-
default: true,
|
|
112
|
-
description: 'Require error message',
|
|
113
|
-
},
|
|
114
|
-
requireStackTrace: {
|
|
115
|
-
type: 'boolean',
|
|
116
|
-
default: false,
|
|
117
|
-
description: 'Require stack trace',
|
|
118
|
-
},
|
|
119
|
-
ignoreInTests: {
|
|
120
|
-
type: 'boolean',
|
|
121
|
-
default: true,
|
|
122
|
-
description: 'Ignore in test files',
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
additionalProperties: false,
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
},
|
|
129
|
-
defaultOptions: [
|
|
130
|
-
{
|
|
131
|
-
requireMessage: true,
|
|
132
|
-
requireStackTrace: false,
|
|
133
|
-
ignoreInTests: true,
|
|
134
|
-
},
|
|
135
|
-
],
|
|
136
|
-
create(context, [options = {}]) {
|
|
137
|
-
const { requireMessage = true, requireStackTrace = false, ignoreInTests = true, } = options || {};
|
|
138
|
-
const filename = context.filename;
|
|
139
|
-
const isTestFile = ignoreInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
|
|
140
|
-
if (isTestFile) {
|
|
141
|
-
return {};
|
|
142
|
-
}
|
|
143
|
-
function checkThrowStatement(node) {
|
|
144
|
-
const missing = [];
|
|
145
|
-
if (requireMessage && !hasErrorMessage(node)) {
|
|
146
|
-
missing.push('message');
|
|
147
|
-
}
|
|
148
|
-
if (requireStackTrace && !hasErrorStack(node)) {
|
|
149
|
-
missing.push('stack trace');
|
|
150
|
-
}
|
|
151
|
-
if (missing.length === 0) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
context.report({
|
|
155
|
-
node,
|
|
156
|
-
messageId: 'missingErrorContext',
|
|
157
|
-
data: {
|
|
158
|
-
missing: missing.join(' and '),
|
|
159
|
-
},
|
|
160
|
-
suggest: [
|
|
161
|
-
{
|
|
162
|
-
messageId: 'addErrorMessage',
|
|
163
|
-
fix: () => null,
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
messageId: 'addErrorStack',
|
|
167
|
-
fix: () => null,
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
messageId: 'useErrorClass',
|
|
171
|
-
fix: () => null,
|
|
172
|
-
},
|
|
173
|
-
],
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
ThrowStatement: checkThrowStatement,
|
|
178
|
-
};
|
|
179
|
-
},
|
|
180
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noMissingErrorContext=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");function hasErrorMessage(node){if(!node.argument){return false}if(node.argument.type==="Identifier"&&node.argument.name!=="undefined"&&node.argument.name!=="NaN"&&node.argument.name!=="Infinity"){return true}if(node.argument.type==="NewExpression"&&node.argument.callee.type==="Identifier"&&(node.argument.callee.name==="Error"||node.argument.callee.name.endsWith("Error"))){if(node.argument.arguments.length>0){const firstArg=node.argument.arguments[0];if(firstArg.type==="Literal"&&typeof firstArg.value==="string"){return firstArg.value.length>0}if(firstArg.type==="TemplateLiteral"){return true}if(node.argument.callee.name!=="Error"&&node.argument.callee.name.endsWith("Error")){return true}}}if(node.argument.type==="Literal"&&typeof node.argument.value==="string"){return node.argument.value.length>0}if(node.argument.type==="TemplateLiteral"){return true}return false}function hasErrorStack(node){if(!node.argument){return false}if(node.argument.type==="Identifier"&&node.argument.name!=="undefined"&&node.argument.name!=="NaN"&&node.argument.name!=="Infinity"){return true}if(node.argument.type==="NewExpression"&&node.argument.callee.type==="Identifier"){const calleeName=node.argument.callee.name;if(calleeName==="Error"||calleeName.endsWith("Error")){return true}}return false}exports.noMissingErrorContext=(0,eslint_devkit_2.createRule)({name:"no-missing-error-context",meta:{type:"suggestion",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-missing-error-context.md",description:"Detects thrown errors without context"},hasSuggestions:true,messages:{missingErrorContext:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.WARNING,issueName:"Missing error context",description:"Thrown error missing {{missing}}",severity:"MEDIUM",fix:"Add error message and use Error class for stack trace",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1128/"}),addErrorMessage:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Message",description:"Add descriptive error message",severity:"LOW",fix:'throw new Error("descriptive message")',documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error"}),addErrorStack:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Error Class",description:"Use Error class for stack trace",severity:"LOW",fix:"throw new Error(message) instead of throw message",documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error"}),useErrorClass:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Use Specific Error",description:"Use specific error class",severity:"LOW",fix:'throw new TypeError("message") or throw new RangeError("message")',documentationLink:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError"})},schema:[{type:"object",properties:{requireMessage:{type:"boolean",default:true,description:"Require error message"},requireStackTrace:{type:"boolean",default:false,description:"Require stack trace"},ignoreInTests:{type:"boolean",default:true,description:"Ignore in test files"}},additionalProperties:false}]},defaultOptions:[{requireMessage:true,requireStackTrace:false,ignoreInTests:true}],create(context,[options={}]){const{requireMessage=true,requireStackTrace=false,ignoreInTests=true}=options||{};const filename=context.filename;const isTestFile=ignoreInTests&&/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);if(isTestFile){return{}}function checkThrowStatement(node){const missing=[];if(requireMessage&&!hasErrorMessage(node)){missing.push("message")}if(requireStackTrace&&!hasErrorStack(node)){missing.push("stack trace")}if(missing.length===0){return}context.report({node,messageId:"missingErrorContext",data:{missing:missing.join(" and ")},suggest:[{messageId:"addErrorMessage",fix:()=>null},{messageId:"addErrorStack",fix:()=>null},{messageId:"useErrorClass",fix:()=>null}]})}return{ThrowStatement:checkThrowStatement}}});
|
|
@@ -1,157 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.noSilentErrors = void 0;
|
|
4
|
-
const eslint_devkit_1 = require("@interlace/eslint-devkit");
|
|
5
|
-
const eslint_devkit_2 = require("@interlace/eslint-devkit");
|
|
6
|
-
function isEmptyCatchBlock(catchClause) {
|
|
7
|
-
const body = catchClause.body;
|
|
8
|
-
if (!body || body.type !== 'BlockStatement') {
|
|
9
|
-
return true;
|
|
10
|
-
}
|
|
11
|
-
const statements = body.body;
|
|
12
|
-
if (statements.length === 0) {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
const nonEmptyStatements = statements.filter((stmt) => stmt.type !== 'EmptyStatement');
|
|
16
|
-
return nonEmptyStatements.length === 0;
|
|
17
|
-
}
|
|
18
|
-
function hasExplanatoryComment(catchClause, sourceCode) {
|
|
19
|
-
const comments = sourceCode.getAllComments();
|
|
20
|
-
const catchStart = catchClause.loc?.start;
|
|
21
|
-
if (!catchStart || !comments.length) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
const explanatoryPatterns = [
|
|
25
|
-
/intentional/i,
|
|
26
|
-
/expected/i,
|
|
27
|
-
/ignore/i,
|
|
28
|
-
/silent/i,
|
|
29
|
-
/noop/i,
|
|
30
|
-
/no-op/i,
|
|
31
|
-
/by design/i,
|
|
32
|
-
/known issue/i,
|
|
33
|
-
/legacy/i,
|
|
34
|
-
/third.?party/i,
|
|
35
|
-
/framework/i,
|
|
36
|
-
/library/i,
|
|
37
|
-
/not implemented/i,
|
|
38
|
-
/todo/i,
|
|
39
|
-
/fixme/i,
|
|
40
|
-
];
|
|
41
|
-
for (const comment of comments) {
|
|
42
|
-
if (comment.loc && catchStart.line - comment.loc.end.line <= 2) {
|
|
43
|
-
const commentText = comment.value.toLowerCase();
|
|
44
|
-
if (explanatoryPatterns.some((pattern) => pattern.test(commentText))) {
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
exports.noSilentErrors = (0, eslint_devkit_2.createRule)({
|
|
52
|
-
name: 'no-silent-errors',
|
|
53
|
-
meta: {
|
|
54
|
-
type: 'problem',
|
|
55
|
-
docs: {
|
|
56
|
-
url: 'https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-silent-errors.md',
|
|
57
|
-
description: 'Detects empty catch blocks',
|
|
58
|
-
},
|
|
59
|
-
hasSuggestions: true,
|
|
60
|
-
messages: {
|
|
61
|
-
silentError: (0, eslint_devkit_1.formatLLMMessage)({
|
|
62
|
-
icon: eslint_devkit_1.MessageIcons.WARNING,
|
|
63
|
-
issueName: 'Silent error',
|
|
64
|
-
description: 'Empty catch block detected - errors are silently ignored',
|
|
65
|
-
severity: 'MEDIUM',
|
|
66
|
-
fix: 'Add error logging or handling in catch block',
|
|
67
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-1186/',
|
|
68
|
-
}),
|
|
69
|
-
addErrorLogging: (0, eslint_devkit_1.formatLLMMessage)({
|
|
70
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
71
|
-
issueName: 'Add Error Logging',
|
|
72
|
-
description: 'Add error logging to catch block',
|
|
73
|
-
severity: 'LOW',
|
|
74
|
-
fix: 'catch (error) { console.error(error); }',
|
|
75
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-1186/',
|
|
76
|
-
}),
|
|
77
|
-
addErrorHandling: (0, eslint_devkit_1.formatLLMMessage)({
|
|
78
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
79
|
-
issueName: 'Add Error Handling',
|
|
80
|
-
description: 'Add error handling to catch block',
|
|
81
|
-
severity: 'LOW',
|
|
82
|
-
fix: 'catch (error) { handleError(error); }',
|
|
83
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-1186/',
|
|
84
|
-
}),
|
|
85
|
-
rethrowError: (0, eslint_devkit_1.formatLLMMessage)({
|
|
86
|
-
icon: eslint_devkit_1.MessageIcons.INFO,
|
|
87
|
-
issueName: 'Rethrow Error',
|
|
88
|
-
description: 'Rethrow error if needed',
|
|
89
|
-
severity: 'LOW',
|
|
90
|
-
fix: 'catch (error) { throw new CustomError(error); }',
|
|
91
|
-
documentationLink: 'https://rules.sonarsource.com/javascript/RSPEC-1186/',
|
|
92
|
-
}),
|
|
93
|
-
},
|
|
94
|
-
schema: [
|
|
95
|
-
{
|
|
96
|
-
type: 'object',
|
|
97
|
-
properties: {
|
|
98
|
-
allowWithComment: {
|
|
99
|
-
type: 'boolean',
|
|
100
|
-
default: false,
|
|
101
|
-
description: 'Allow empty catch if comment explains why',
|
|
102
|
-
},
|
|
103
|
-
ignoreInTests: {
|
|
104
|
-
type: 'boolean',
|
|
105
|
-
default: true,
|
|
106
|
-
description: 'Ignore in test files',
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
additionalProperties: false,
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
defaultOptions: [
|
|
114
|
-
{
|
|
115
|
-
allowWithComment: false,
|
|
116
|
-
ignoreInTests: true,
|
|
117
|
-
},
|
|
118
|
-
],
|
|
119
|
-
create(context, [options = {}]) {
|
|
120
|
-
const { allowWithComment = false, ignoreInTests = true } = options || {};
|
|
121
|
-
const filename = context.filename;
|
|
122
|
-
const isTestFile = ignoreInTests && /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);
|
|
123
|
-
if (isTestFile) {
|
|
124
|
-
return {};
|
|
125
|
-
}
|
|
126
|
-
const sourceCode = context.sourceCode;
|
|
127
|
-
function checkCatchClause(node) {
|
|
128
|
-
if (!isEmptyCatchBlock(node)) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (allowWithComment && hasExplanatoryComment(node, sourceCode)) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
context.report({
|
|
135
|
-
node,
|
|
136
|
-
messageId: 'silentError',
|
|
137
|
-
suggest: [
|
|
138
|
-
{
|
|
139
|
-
messageId: 'addErrorLogging',
|
|
140
|
-
fix: () => null,
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
messageId: 'addErrorHandling',
|
|
144
|
-
fix: () => null,
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
messageId: 'rethrowError',
|
|
148
|
-
fix: () => null,
|
|
149
|
-
},
|
|
150
|
-
],
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
CatchClause: checkCatchClause,
|
|
155
|
-
};
|
|
156
|
-
},
|
|
157
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.noSilentErrors=void 0;const eslint_devkit_1=require("@interlace/eslint-devkit");const eslint_devkit_2=require("@interlace/eslint-devkit");function isEmptyCatchBlock(catchClause){const body=catchClause.body;if(!body||body.type!=="BlockStatement"){return true}const statements=body.body;if(statements.length===0){return true}const nonEmptyStatements=statements.filter(stmt=>stmt.type!=="EmptyStatement");return nonEmptyStatements.length===0}function hasExplanatoryComment(catchClause,sourceCode){const comments=sourceCode.getAllComments();const catchStart=catchClause.loc?.start;if(!catchStart||!comments.length){return false}const explanatoryPatterns=[/intentional/i,/expected/i,/ignore/i,/silent/i,/noop/i,/no-op/i,/by design/i,/known issue/i,/legacy/i,/third.?party/i,/framework/i,/library/i,/not implemented/i,/todo/i,/fixme/i];for(const comment of comments){if(comment.loc&&catchStart.line-comment.loc.end.line<=2){const commentText=comment.value.toLowerCase();if(explanatoryPatterns.some(pattern=>pattern.test(commentText))){return true}}}return false}exports.noSilentErrors=(0,eslint_devkit_2.createRule)({name:"no-silent-errors",meta:{type:"problem",docs:{url:"https://github.com/ofri-peretz/eslint/blob/main/packages/eslint-plugin-reliability/docs/rules/no-silent-errors.md",description:"Detects empty catch blocks"},hasSuggestions:true,messages:{silentError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.WARNING,issueName:"Silent error",description:"Empty catch block detected - errors are silently ignored",severity:"MEDIUM",fix:"Add error logging or handling in catch block",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorLogging:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Logging",description:"Add error logging to catch block",severity:"LOW",fix:"catch (error) { console.error(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),addErrorHandling:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Add Error Handling",description:"Add error handling to catch block",severity:"LOW",fix:"catch (error) { handleError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"}),rethrowError:(0,eslint_devkit_1.formatLLMMessage)({icon:eslint_devkit_1.MessageIcons.INFO,issueName:"Rethrow Error",description:"Rethrow error if needed",severity:"LOW",fix:"catch (error) { throw new CustomError(error); }",documentationLink:"https://rules.sonarsource.com/javascript/RSPEC-1186/"})},schema:[{type:"object",properties:{allowWithComment:{type:"boolean",default:false,description:"Allow empty catch if comment explains why"},ignoreInTests:{type:"boolean",default:true,description:"Ignore in test files"}},additionalProperties:false}]},defaultOptions:[{allowWithComment:false,ignoreInTests:true}],create(context,[options={}]){const{allowWithComment=false,ignoreInTests=true}=options||{};const filename=context.filename;const isTestFile=ignoreInTests&&/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(filename);if(isTestFile){return{}}const sourceCode=context.sourceCode;function checkCatchClause(node){if(!isEmptyCatchBlock(node)){return}if(allowWithComment&&hasExplanatoryComment(node,sourceCode)){return}context.report({node,messageId:"silentError",suggest:[{messageId:"addErrorLogging",fix:()=>null},{messageId:"addErrorHandling",fix:()=>null},{messageId:"rethrowError",fix:()=>null}]})}return{CatchClause:checkCatchClause}}});
|