fix(frontend): treat cancelled scans as non-success in finalizeScan (MCP-2755)#700
Conversation
Deploying mcpproxy-docs with
|
| Latest commit: |
a0ac9cf
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://78576b3c.mcpproxy-docs.pages.dev |
| Branch Preview URL: | https://fix-scan-cancelled-non-succe.mcpproxy-docs.pages.dev |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
📦 Build ArtifactsWorkflow Run: View Run Available Artifacts
How to DownloadOption 1: GitHub Web UI (easiest)
Option 2: GitHub CLI gh run download 27684628976 --repo smart-mcp-proxy/mcpproxy-go
|
🤖 Codex review — REQUEST_CHANGES (1×P2)[P2] Refresh server state after cancelled scans —
|
Codex P2 on PR #700: the cancelled-scan branch in finalizeScan returned before serversStore.fetchServers(), so after clearScanRunState() dropped scanLoading the Security tab kept deriving securityScanStatus='scanning' from the stale store and the spinner never cleared. Extract a pure, table-driven scanFinalizeEffects() reducer (mirrors the MCP-2740 decideScanReconcile extraction) that encodes per-outcome side effects. Cancellation now refreshes the store (clearing the spinner) while still skipping the report reload and the success toast. finalizeScan consumes the reducer; new unit cases cover cancelled/success/error effects. Related #700 Related MCP-2755
|
Addressed the P2 in Fix: extracted a pure, table-driven Test: new |
🤖 Codex re-review (round 2) — REQUEST_CHANGES (1×P2)[P2] Clear stale report when finalizing cancellations —
|
… on cancel Codex round-2 P2 on PR #700: a tab opened mid-scan loads a previous report, and a cancelled scan may produce none — so finalizeScan must also CLEAR the rendered report on cancel, not just skip the reload. Otherwise the Security tab renders a stale report after a cancel. Add a clearReport effect to scanFinalizeEffects (true for cancel) and extract applyScanFinalize() — the ordered side-effect applier — out of the component so the full contract is test-driven against fake handlers. finalizeScan now wires its refs/stores into applyScanFinalize. Full cancel contract now: stopScanPolling + clearScanRunState (spinner off), clear scanReport (no stale report), refresh server store (status not 'scanning'), 'Scan cancelled' toast, NO success toast, NO report reload. New behavioral test: tab-open-mid-scan stale report → cancelled via poll → asserts scanLoading=false, scanReport cleared, store refreshed, no success toast. plus success/error contract tests. Related #700 Related MCP-2755
|
Round-2 P2 (stale On a terminal
Net: after cancel the Security tab shows neither spinner nor stale report, and reflects the cancelled state. Implementation: added a Test (as requested): Full frontend unit suite 209 passed, |
🤖 Codex re-review (round 3) — REQUEST_CHANGES (1×P2)[P2] Render a neutral cancelled state —
|
… no blank) Codex round-3 P2 on PR #700: clearing scanReport on cancel exposed a TEMPLATE gap — the Security tab header fell back to server.security_scan (a misleading 0/100) and the detail section (v-if scanReport) went blank. Add a reactive scanCancelled flag (set on every cancel path, cleared on a new scan / success / error) plus two pure, tested visibility helpers: - cancelledPanelVisible() → renders a neutral 'Scan cancelled' detail panel - riskScoreVisible() → suppresses the header score after a cancel Wire scanCancelled across all cancel paths: finalizeScan (via a new setCancelled handler + markCancelled effect in applyScanFinalize), the in-tab Cancel button, the loadScanReport reconcile branch, and the terminal-status safety-net watcher. Net: after a cancelled scan the Security tab shows neither the spinner, a stale report, nor the stale stored score — it shows an explicit 'Scan cancelled' state. Tests: cancelledPanelVisible + riskScoreVisible pure-helper cases, setCancelled wiring in applyScanFinalize, and an end-to-end assertion that a cancelled scan yields cancelled-panel=visible + risk-score=hidden (not 0/100, not blank). Related #700 Related MCP-2755
|
Round-3 P2 (template gap) addressed in Template: added a reactive
Flag lifecycle (set on every cancel path, cleared on new scan/success/error):
Tests: Full frontend unit suite 219 passed, |
🤖 Codex re-review (round 4) — REQUEST_CHANGES (2×P2)Two more cancelled-panel state edges (fresh-load skip; Direction change (scope reduction): the cancelled-UI-panel approach keeps uncovering state-management edges and this is a low-priority polish PR. Please revert the
Net diff ≈ the toast change only. Keep the one unit test asserting a cancelled scan does not fire the success toast. Reviewed via |
…MCP-2755) Codex P3 from #698: the scan-reconcile reducer marked cancelled/canceled as terminal but not an error, so finalizeScan took the success path and could fire the 'Scan Complete' toast for a scan cancelled from another tab or during a cancel/status race. Minimal fix (per PR #700 review direction to avoid scope creep): - decideScanReconcile now flags cancelled/canceled as isCancelled (terminal, non-success), distinct from isError. - finalizeScan suppresses the success toast for a cancelled scan and shows a neutral 'Scan cancelled' info notice instead, via a small pure finalizeToastKind helper. Report/score rendering is left exactly as before (pre-existing, out of scope) — no scanReport clearing, no cancelled panel, no extra ref. Tests: reducer flags cancelled as terminal-non-success; finalizeToastKind — a cancelled scan does NOT fire the success toast. Related #698 Related MCP-2755
ff0af9a to
a0ac9cf
Compare
|
Agreed — reduced to the minimal original-P3 fix and collapsed the branch to a single clean commit ( Reverted: Kept (the whole change):
Test: Full frontend unit suite 203 passed, |
🤖 Codex review — ACCEPT ✅
No P0–P2 findings after reducing to the minimal scope (suppress the "Scan Complete" success toast on cancel; cancelled-panel/ Reviewed via |
Summary
Low-priority polish from the Codex review of PR #698 (MCP-2740, merged).
In
frontend/src/utils/scanState.ts, the scan-reconcile reducer markedcancelled/canceledas terminal but not an error, sofinalizeScan(ServerDetail.vue) took the success path: it reloaded a report and showed the 'Scan Complete' toast. For a scan cancelled from another tab or during a cancel/status race this is misleading, and it could surface a stale previous report (a cancelled scan may not have produced one).Change
decideScanReconcilenow returns a newisCancelledflag (true forcancelled/canceled), distinct fromisError. Cancellation is terminal but neither error nor success.finalizeScangains a non-success cancelled branch: suppresses the 'Scan Complete' success toast, skips the report reload (avoids surfacing a stale report), and surfaces a neutral 'Scan cancelled' info toast instead — only when a scan was actually in flight in this tab (mirrors the existingwasLoadinggate).Tests
frontend/tests/unit/scan-state-reconcile.spec.ts: cancelled/canceled →finalize:true, isError:false, isCancelled:true; and non-cancelled statuses →isCancelled:false.vue-tsc --noEmit: clean.make build: green.Related #698
Related MCP-2755