From fcd4703ea884acb253af168c05a26b41ea7358ed Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Tue, 30 Oct 2018 16:04:32 -0700 Subject: [PATCH] Don't lint against Hooks after conditional throw Seems like this should be OK. Fixes #14038. Now when tracking paths, we completely ignore segments that end in a throw. In https://eslint.org/docs/developer-guide/code-path-analysis I don't see a way to detect throws other than manually tracking them, so that's what I've done. --- .../__tests__/ESLintRulesOfHooks-test.js | 9 +++++++++ packages/eslint-plugin-react-hooks/src/RulesOfHooks.js | 8 ++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js index b8807db3c56f4..410f5d1646f69 100644 --- a/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js +++ b/packages/eslint-plugin-react-hooks/__tests__/ESLintRulesOfHooks-test.js @@ -261,6 +261,15 @@ eslintTester.run('react-hooks', ReactHooksESLintRule, { useState(); } `, + ` + // Valid because exceptions abort rendering + function RegressionTest() { + if (page == null) { + throw new Error('oh no!'); + } + useState(); + } + `, ], invalid: [ { diff --git a/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js b/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js index e77afbf3c6822..571c7b506f825 100644 --- a/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js +++ b/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js @@ -139,7 +139,9 @@ export default { // Compute `paths` and cache it. Guarding against cycles. cache.set(segment.id, null); - if (segment.prevSegments.length === 0) { + if (codePath.thrownSegments.includes(segment)) { + paths = 0; + } else if (segment.prevSegments.length === 0) { paths = 1; } else { paths = 0; @@ -199,7 +201,9 @@ export default { // Compute `paths` and cache it. Guarding against cycles. cache.set(segment.id, null); - if (segment.nextSegments.length === 0) { + if (codePath.thrownSegments.includes(segment)) { + paths = 0; + } else if (segment.nextSegments.length === 0) { paths = 1; } else { paths = 0;