fix(ui-react): surface swallowed errors in ConfirmDialog delete flows#6168
fix(ui-react): surface swallowed errors in ConfirmDialog delete flows#6168
Conversation
The confirm dialog swallowed any error from the delete mutation, leaving the user with a stuck dialog and no explanation. Track the error locally and render it via ConfirmDialog's children so the dialog stays open with a visible message on failure.
Same swallowed-error bug as the firewall rules page — catch the mutation rejection, keep the dialog open, and render the message via ConfirmDialog children.
Same swallowed-error bug as the other confirm dialogs — catch the mutation rejection, keep the dialog open, and render the message via ConfirmDialog children.
Same swallowed-error bug as the other confirm dialogs — catch the mutation rejection, keep the dialog open, and render the message via ConfirmDialog children.
Same swallowed-error bug as the other confirm dialogs — catch the mutation rejection, keep the dialog open, and render the message via ConfirmDialog children. The large diff is from the formatter normalizing the whole file; the intended change is the new deleteError state plus the closeDelete / confirmDelete handlers wired to ConfirmDialog. Fixes: #6165
|
Claude finished @luizhf42's task in 4m 17s —— View job Code Review CompleteReviewed 8 files across code quality, security, testing, TypeScript/React patterns, and architecture — no issues found. The code looks good as-is. All five pages correctly mirror the If you push additional changes and want a new review, tag |
What
Five confirm-dialog delete flows in the console silently swallowed mutation errors on failure, leaving the dialog stuck open with no explanation. Each now catches the rejection, keeps the dialog open, and renders a human-readable error inline.
Why
ConfirmDialogintentionally swallows exceptions fromonConfirmand expects consumers to pre-catch and manage their own error state (the component's comment points atKeyDeleteDialogas the reference implementation). Three pages listed in #6165 — firewall rules, public keys, API keys — violated that contract with an uncaughtawait mutateAsyncinsideonConfirm. A grep ofapps/console/src/pagessurfaced two more with the same pattern: team members and web endpoints.Closes #6165
Changes
KeyDeleteDialogshape — localdeleteErrorstate,closeDeletehandler that resets both the target and the error,confirmDeletehandler that wrapsmutateAsyncin try/catch and falls back to"Failed to delete …"when the rejection isn't anError. Success-path side effects (page decrement, dialog close) only run on success.ConfirmDialog— matching the existing pattern used byDeleteNamespaceDialog.test.tsxandKeyDeleteDialog.test.tsx. Coverage asserts: the rawError.messageis shown, the generic fallback is shown for non-Errorrejections, the dialog closes on success, and stale error text clears on cancel+reopen.Testing
The large line count on
WebEndpoints.tsxis the project formatter normalizing the whole file on first edit — the intended change is the new state + handlers plus theConfirmDialogwiring (same shape as the other four pages). Review that file's diff with whitespace ignored to see the real change.Reviewers can exercise the error path manually by opening any of the five pages with the API unreachable (or returning 4xx/5xx), clicking a destructive action, and confirming: the dialog should stay open, the confirm button should re-enable, and a red error message should appear below the description.