fix(AuthVisible): move hooks above early return to satisfy Rules of H…#5615
fix(AuthVisible): move hooks above early return to satisfy Rules of H…#5615kashish00208 wants to merge 9 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: kashish00208 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
illume
left a comment
There was a problem hiding this comment.
Thanks for this PR.
A few of the commits don't quite follow the project guidelines. We use Linux kernel style for git commits — have a look at the contributing guide and previous commits with git log.
Commits that need attention
fix(AuthVisible): move hooks above early return to satisfy Rules of Hooks— Missingarea: descriptionprefix — e.g.frontend: HomeButton: Fix so it navigates to homeorbackend: config: Add enable-dynamic-clusters flag.
Commit guidelines
- Use atomic commits focused on a single change.
- Use the title format
<area>: <Description of changes>— description must start with a capital letter. - Keep the title under 72 characters (soft requirement).
- Explain the intention and why the change is needed.
- Make commit titles meaningful and describe what changed.
- Do not add code that a later commit rewrites; squash or reorder commits instead.
- Do not include
Fixes #NNin commit messages.
Good examples:
frontend: HomeButton: Fix so it navigates to homebackend: config: Add enable-dynamic-clusters flag
There was a problem hiding this comment.
Pull request overview
This PR aims to fix a react-hooks/rules-of-hooks violation in AuthVisible by ensuring useQuery/useEffect are called before any early returns, while keeping the existing authorization gating via React Query’s enabled flag.
Changes:
- Moved the invalid-
authVerbearly return belowuseQueryanduseEffect. - Removed prior per-line ESLint disables for hook rules.
Comments suppressed due to low confidence (4)
frontend/src/components/common/Resource/AuthVisible.tsx:93
useEffectreferencesvisible, butvisibleis declared after the effect and is never initialized on the invalid-authVerbearly-return path. IfauthVerbis invalid, the component still mounts (renders null) and the effect callback will run later and throw aReferenceErrorwhen it tries to readvisible. Initializevisible(and anyisValidVerbflag) before the effect and before any return, or computealloweddirectly fromdatainside the effect without referencing a potentially uninitialized variable.
useEffect(() => {
if (data) {
onAuthResult?.({
allowed: visible,
reason: data.status?.reason ?? '',
});
}
frontend/src/components/common/Resource/AuthVisible.tsx:70
useQueryis now executed even whenauthVerbis invalid. Becauseenabledonly checks!!item, an invalid verb will still trigger the authorization request andonAuthResultcallbacks (even though the component returns null). To preserve the previous behavior and avoid unnecessary/invalid API calls, include the verb validation inenabled(e.g.,enabled: !!item && isValidVerb).
const { data } = useQuery<any>({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
subresource,
frontend/src/components/common/Resource/AuthVisible.tsx:69
itemClassis typed asKubeObjectClass | null, butqueryKeyunconditionally dereferencesitemClass.apiName/itemClass.apiVersion. Ifitemisnull/undefinedat runtime (allowed by the prop type and possible from callsites likenamespaces[0]), this will throw during render even though the query is disabled. Guard these fields (optional chaining / fallbacks) and/or ensureenabledalso requires a non-nullitemClassbefore building a key that dereferences it.
This issue also appears in the following locations of the same file:
- line 62
- line 87
- line 87
const itemClass: KubeObjectClass | null = (item as KubeObject)?._class?.() ?? item;
const itemName = (item as KubeObject)?.getName?.();
const { data } = useQuery<any>({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
frontend/src/components/common/Resource/AuthVisible.tsx:95
- The
useEffectdependency array is now[data], but the effect body also usesonAuthResultand (indirectly)authVerb/visible. In CI,react-hooks/exhaustive-depsis enabled and will warn here, and at runtime this can call a staleonAuthResultif the prop changes. Add the missing dependencies (or restructure to avoid capturing them) instead of relying on an incomplete dependency list.
useEffect(() => {
if (data) {
onAuthResult?.({
allowed: visible,
reason: data.status?.reason ?? '',
});
}
}, [data]);
skoeva
left a comment
There was a problem hiding this comment.
hi, could you address the linter failures? thanks
75a944e to
b088c3f
Compare
Thanks , I’ve addressed the linter failures and pushed the updates. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
frontend/src/components/common/Resource/AuthVisible.tsx:69
- The invalid
authVerbguard was moved belowuseQuery, butuseQueryis stillenabled: !!item. That means an invalid verb will still trigger an authorization request even though the warning says the check is being skipped, andonAuthResultmay fire for an invalid verb. Consider gating the query with something likeenabled: !!item && VALID_AUTH_VERBS.includes(authVerb)(and similarly avoid side-effects when the verb is invalid).
const { data } = useQuery<any>({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
frontend/src/components/common/Resource/AuthVisible.tsx:69
itemis typed asKubeObject | KubeObjectClass | null, butitemClasscan benullwhenitemisnull. ThequeryKeystill unconditionally readsitemClass.apiName/apiVersion, which will throw even whenenabledis false (becausequeryKeyis built during render). Use optional chaining/defaults in the key and include!!itemClassinenabled, or otherwise ensure safe key construction whenitemis null.
const itemClass: KubeObjectClass | null = (item as KubeObject)?._class?.() ?? item;
const itemName = (item as KubeObject)?.getName?.();
const { data } = useQuery<any>({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
illume
left a comment
There was a problem hiding this comment.
Thanks for these changes.
Can you please have a look at the git commits to see if they meet the contribution guidelines? We use a Linux kernel style of git commits. See the contributing guide for general context, and please see previous git commits with git log for examples.
Commits that need attention
frontend : Fix AuthVisible useEffect— Missingarea: descriptionprefix — e.g.frontend: HomeButton: Fix so it navigates to homeorbackend: config: Add enable-dynamic-clusters flag.
Commit guidelines
- Use atomic commits focused on a single change.
- Use the title format
<area>: <Description of changes>— description must start with a capital letter. - Keep the title under 72 characters (soft requirement).
- Explain the intention and why the change is needed.
- Make commit titles meaningful and describe what changed.
- Do not add code that a later commit rewrites; squash or reorder commits instead.
- Do not include
Fixes #NNin commit messages.
Good examples:
frontend: HomeButton: Fix so it navigates to homebackend: config: Add enable-dynamic-clusters flag
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
frontend/src/components/common/Resource/AuthVisible.tsx:72
- Moving the invalid
authVerbcheck below the hooks changes behavior:useQuerycan still run with an invalid verb (sinceenabledis only!!item), anduseEffectmay still callonAuthResultbased on query data even though the component ultimately returnsnull. It can also now throw before reaching the warning/return whenitemis null becausequeryKeydereferencesitemClass.apiName/apiVersion. Consider computingisValidAuthVerbup-front and using it to (a) gate the query viaenabled, (b) avoid dereferencingitemClassin the queryKey whenitemis null, and (c) guard theonAuthResultside-effect when the verb is invalid so the prior “skip authorization check” behavior is preserved.
const { data } = useQuery<any>({
enabled: !!item,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
subresource,
namespace,
],
Yes, the Git commits follow the contribution guidelines. |
illume
left a comment
There was a problem hiding this comment.
Thanks for this PR.
A few of the commits don't quite follow the project guidelines. We use Linux kernel style for git commits — have a look at the contributing guide and previous commits with git log.
Commits that need attention
frontend : Fix AuthVisible useEffect— Missingarea: descriptionprefix — e.g.frontend: HomeButton: Fix so it navigates to homeorbackend: config: Add enable-dynamic-clusters flag.frontend : Re-add a justified ESLint disable— Missingarea: descriptionprefix — e.g.frontend: HomeButton: Fix so it navigates to homeorbackend: config: Add enable-dynamic-clusters flag.
Commit guidelines
- Use atomic commits focused on a single change.
- Use the title format
<area>: <Description of changes>— description must start with a capital letter. - Keep the title under 72 characters (soft requirement).
- Explain the intention and why the change is needed.
- Make commit titles meaningful and describe what changed.
- Do not add code that a later commit rewrites; squash or reorder commits instead.
- Do not include
Fixes #NNin commit messages.
Good examples:
frontend: HomeButton: Fix so it navigates to homebackend: config: Add enable-dynamic-clusters flag
3a1cf73 to
940a10a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
frontend/src/components/common/Resource/AuthVisible.tsx:70
itemis typed asKubeObject | KubeObjectClass | null, butqueryKeyunconditionally dereferencesitemClass.apiName/itemClass.apiVersion. React Query evaluatesqueryKeyduring render even whenenabledis false, so passingitem={null}will still throw at render time. Consider guardingitemClassaccess (e.g., use optional chaining / fallback values in the key) so the component can safely render whenitemis null.
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
illume
left a comment
There was a problem hiding this comment.
Thanks for the contribution.
Could you take a look at the commit messages in this PR? We follow a Linux kernel style for git commits — see the contributing guide and git log for examples.
Commits that need attention
frontend : Authvisible remove duplicate work— Missingarea: descriptionprefix — e.g.frontend: HomeButton: Fix so it navigates to homeorbackend: config: Add enable-dynamic-clusters flag.
Commit guidelines
- Use atomic commits focused on a single change.
- Use the title format
<area>: <Description of changes>— description must start with a capital letter. - Keep the title under 72 characters (soft requirement).
- Explain the intention and why the change is needed.
- Make commit titles meaningful and describe what changed.
- Do not add code that a later commit rewrites; squash or reorder commits instead.
- Do not include
Fixes #NNin commit messages.
Good examples:
frontend: HomeButton: Fix so it navigates to homebackend: config: Add enable-dynamic-clusters flag
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
frontend/src/components/common/Resource/AuthVisible.tsx:70
itemis typed as nullable, but thequeryKeyunconditionally dereferencesitemClass.apiName/itemClass.apiVersion. Whenitemisnull,itemClassbecomesnulland this will throw during render even though the query is disabled. Make the key construction null-safe (e.g., optional chaining / default placeholders) or otherwise guard againstitem === nullwithout violating the Rules of Hooks.
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
bcfd5bb to
a7d1346
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
frontend/src/components/common/Resource/AuthVisible.tsx:71
itemis typed as nullable, butitemClasswill benullwhenitemisnull, and thequeryKeyunconditionally readsitemClass.apiName/apiVersion. React Query evaluatesqueryKeyeven whenenabledis false, so this will throw at render time. Make thequeryKeynull-safe (e.g.,itemClass?.apiName/itemClass?.apiVersion) and consider including!!itemClassin theenabledcondition (and/or returning a stable placeholder key) soAuthVisiblecan safely render withitem === null.
const itemClass: KubeObjectClass | null = (item as KubeObject)?._class?.() ?? item;
const itemName = (item as KubeObject)?.getName?.();
const { data } = useQuery<any>({
enabled: !!item && isValidVerb,
queryKey: [
'authVisible',
itemName,
itemClass.apiName,
itemClass.apiVersion,
authVerb,
illume
left a comment
There was a problem hiding this comment.
Thanks for working on this.
Would you mind addressing the open Copilot review comments? Please mark each comment as resolved after addressing it.
|
@illume take a look at this PR every copilot comment is resolved , let me know if any changes are required ! |
illume
left a comment
There was a problem hiding this comment.
Thanks for this PR.
The open review comments from Copilot still need attention — can you have a look? Once addressed, please mark them as resolved.
|
|
||
| const itemClass: KubeObjectClass | null = (item as KubeObject)?._class?.() ?? item; | ||
| const itemName = (item as KubeObject)?.getName?.(); | ||
| const cluster = (item as KubeObject)?.cluster ?? getCluster(); |
illume
left a comment
There was a problem hiding this comment.
Thanks for these changes.
Can you please address the open review comments? Once you've resolved each one, please mark it as resolved.
Fixes #5187
Changes
Moves
useQueryanduseEffectabove the early return inAuthVisibleto ensure hooks are always executed in the same order on every render, fixing thereact-hooks/rules-of-hooksESLint error while preserving existing authorization logic via conditionalenabledhandling inuseQuery.