fix(workspace-crud): add missing descRows.Err() check in CascadeDelete #1714
Reference in New Issue
Block a user
Delete Branch "fix/workspace-crud-descrows-err"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The descendant CTE query loop in
CascadeDeletedid not checkdescRows.Err()after iteration, silently truncating descendant IDs on mid-stream errors. Also switched inlinedescRows.Close()todeferfor panic safety.Five-axis review for PR #1714.
Correctness: REQUEST_CHANGES. The core CascadeDelete fix does not actually propagate descendant iteration failures. After descRows.Next(), the code logs descRows.Err() but still continues building allIDs and deleting. If the recursive descendant query fails mid-stream, CascadeDelete can proceed with a truncated descendantIDs set and delete only part of the subtree while returning success. This is the exact failure mode described in the PR body. Since CascadeDelete already returns an error, descRows.Err() should abort the operation, e.g. return nil, nil, fmt.Errorf("descendant rows: %w", err), before constructing allIDs.
Robustness: logging-only rows.Err handling may be acceptable in best-effort list/broadcast/sweep paths, but not for destructive workspace deletion where partial discovery changes the mutation set.
Security: no new auth, secret, or input-validation surface. The risk is availability/data consistency from partial deletion, not credential exposure.
Performance: no concerning loops or N+1 behavior; rows.Err checks are constant overhead.
Readability: the added checks are easy to read, but the CascadeDelete handling contradicts the function contract and PR intent.
CI/status checked on
f430894: statuses are accessible; all-required, Platform Go, lint, secret scan, and E2E contexts are green, while review-gate contexts are pending/failing for approvals.APPROVED
5-axis review on
c14436b8:Correctness: The prior blocker is addressed.
CascadeDeletenow defersdescRows.Close()and returns an error immediately whendescRows.Err()is non-nil, before constructingallIDsor running deletion side effects. That prevents the truncated-descendant partial-delete failure mode called out in review_id=5564. The addedTestCascadeDelete_DescendantRowsErrorcovers the mid-iteration rows error path, and the follow-up commit fixes sqlmock setup so the injected RowError is actually exercised.Robustness: Destructive deletion now fails closed on descendant iteration failure. Other best-effort list/sweep paths log rows errors, which is acceptable for observability-only surfaces.
Security: No new auth, secret, or input-validation surface; this is a consistency/availability fix.
Performance: rows.Err checks are constant overhead and do not add query work.
Readability: The CascadeDelete control flow now matches the function contract and PR intent.
Peer 2nd-review per CTO carve-out. 5-axis lens clean; deferring to Code Reviewer (2) review_id=5708 (CascadeDelete returns error on descRows.Err() before side effects). BP unblock for merge.
/sop-n/a qa-review
/sop-n/a security-review