From 8f90e0521debcbabbee809a25f8ebdb8b5d1db1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Eberhardt?= Date: Sun, 8 Sep 2024 11:33:10 +0200 Subject: [PATCH] support try, catch, finally. improve code --- examples/vite-project/main.js | 11 +++ lib/rules/throw-documentation.mjs | 92 +++++++++++--------------- lib/tests/throw-documentation.test.mjs | 48 ++++++++++++++ 3 files changed, 98 insertions(+), 53 deletions(-) diff --git a/examples/vite-project/main.js b/examples/vite-project/main.js index 7488485..ed8a9f0 100644 --- a/examples/vite-project/main.js +++ b/examples/vite-project/main.js @@ -11,7 +11,18 @@ function test2() { const test3 = () => { try { + console.log("Test"); + } catch { throw new Error("Test error"); + } +}; + +/** + * @throws {Error} + */ +const test4 = () => { + try { + console.log("Test"); } finally { throw new Error("Test error"); } diff --git a/lib/rules/throw-documentation.mjs b/lib/rules/throw-documentation.mjs index 8349f7e..67b139d 100644 --- a/lib/rules/throw-documentation.mjs +++ b/lib/rules/throw-documentation.mjs @@ -17,65 +17,51 @@ export default { schema: [], // no options }, create(context) { - return { - ArrowFunctionExpression(node) { - const sourceCode = context.sourceCode; - const jsDocComment = sourceCode.getJSDocComment(node); - - // if (!jsDocComment) return; // If there's no JSDoc, skip - - const hasThrow = node.body.body?.some( - (statement) => statement.type === "ThrowStatement" - ); - - if (hasThrow) { - // Missing JSDoc @throws - if (!jsDocComment) { - context.report({ - node: node, - messageId: "missingThrows", - }); - return; - } - - const throwsTag = jsDocComment.value.includes("@throws"); - if (!throwsTag) { - context.report({ - node: node, - messageId: "missingThrows", - }); - } + /** @param {import("estree").Statement[]} block */ + function hasThrowInBlock(block = []) { + return block.some((statement) => { + if (statement.type === "ThrowStatement") return true; + if (statement.type === "TryStatement") { + return ( + (statement.handler && + hasThrowInBlock(statement.handler.body.body)) || + (statement.finalizer && hasThrowInBlock(statement.finalizer.body)) + ); } - }, - FunctionDeclaration(node) { - const sourceCode = context.sourceCode; - const jsDocComment = sourceCode.getJSDocComment(node); + return false; + }); + } - // if (!jsDocComment) return; // If there's no JSDoc, skip + /** @param {(import("estree").ArrowFunctionExpression | (import("estree").FunctionDeclaration)) & import("eslint").Rule.NodeParentExtension} node */ + function checkThrows(node) { + const sourceCode = context.sourceCode; + const jsDocComment = sourceCode.getJSDocComment(node); - const hasThrow = node.body.body?.some( - (statement) => statement.type === "ThrowStatement" - ); + const hasThrow = hasThrowInBlock(node.body.body); - if (hasThrow) { - // Missing JSDoc @throws - if (!jsDocComment) { - context.report({ - node: node, - messageId: "missingThrows", - }); - return; - } + if (hasThrow) { + // Missing JSDoc @throws + if (!jsDocComment) { + context.report({ + node: node, + messageId: "missingThrows", + }); + return; + } - const throwsTag = jsDocComment.value.includes("@throws"); - if (!throwsTag) { - context.report({ - node: node, - messageId: "missingThrows", - }); - } + const throwsTag = jsDocComment.value.includes("@throws"); + if (!throwsTag) { + context.report({ + node: node, + messageId: "missingThrows", + }); } - }, + } + } + + return { + ArrowFunctionExpression: checkThrows, + FunctionDeclaration: checkThrows, }; }, }; diff --git a/lib/tests/throw-documentation.test.mjs b/lib/tests/throw-documentation.test.mjs index 7b67d4b..38bc88f 100644 --- a/lib/tests/throw-documentation.test.mjs +++ b/lib/tests/throw-documentation.test.mjs @@ -52,6 +52,30 @@ ruleTester.run("throw-documentation", rule, { } `, }, + { + code: ` + /** @throws {Error} */ + const test = () => { + try { + console.log('test'); + } catch { + throw new Error("Test error"); + } + } + `, + }, + { + code: ` + /** @throws {Error} */ + const test = () => { + try { + console.log('test'); + } finally { + throw new Error("Test error"); + } + } + `, + }, // Arrow Function Expression { code: ` @@ -114,6 +138,30 @@ ruleTester.run("throw-documentation", rule, { `, errors: [{ messageId: "missingThrows" }], }, + { + code: ` + const test = () => { + try { + console.log('test'); + } catch { + throw new Error("Test error"); + } + } + `, + errors: [{ messageId: "missingThrows" }], + }, + { + code: ` + const test = () => { + try { + console.log('test'); + } finally { + throw new Error("Test error"); + } + } + `, + errors: [{ messageId: "missingThrows" }], + }, { code: ` /**