fix: wait for server confirmation before navigating after pad delete#7432
fix: wait for server confirmation before navigating after pad delete#7432JohnMcLear wants to merge 2 commits intoether:developfrom
Conversation
The delete pad handler navigated to '/' immediately after sending the
PAD_DELETE message. Firefox (and some mobile Chrome) would close the
WebSocket before the message reached the server, causing the delete to
silently fail.
Now the client waits for the server's {disconnect: 'deleted'} response
before navigating. Also awaits pad.remove() on the server side to
ensure the operation completes before the response is sent.
Fixes: ether#7306
Fixes: ether#7311
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Review Summary by QodoFix pad deletion race condition with server confirmation
WalkthroughsDescription• Wait for server confirmation before navigating after pad deletion • Prevents race condition where browser closes WebSocket prematurely • Await pad.remove() on server to ensure deletion completes • Fixes silent pad deletion failures in Firefox and mobile Chrome Diagramflowchart LR
A["Client: Delete Pad Click"] --> B["Send PAD_DELETE Message"]
B --> C["Listen for disconnect: deleted"]
C --> D["Server: Await pad.remove()"]
D --> E["Send disconnect Response"]
E --> F["Client: Navigate to Home"]
File Changes1. src/node/handler/PadMessageHandler.ts
|
Code Review by Qodo
1. Missing PAD_DELETE regression test
|
- Listen for 'shout' event to show error when non-creator tries to delete (server sends shoutMessage instead of deleting) - Add 5-second timeout fallback in case the server doesn't respond (socket dropped, server crashed, etc.) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| // Wait for the server to confirm deletion before navigating away. | ||
| // Navigating immediately caused a race condition where the browser | ||
| // (especially Firefox) would close the WebSocket before the delete | ||
| // message reached the server. See #7306. | ||
| pad.socket.on('message', (data: any) => { | ||
| if (data && data.disconnect === 'deleted') { | ||
| window.location.href = '/'; | ||
| } | ||
| }); | ||
| pad.collabClient.sendMessage({type: 'PAD_DELETE', data:{padId: pad.getPadId()}}); | ||
| // redirect to home page after deletion | ||
| window.location.href = '/'; | ||
| } |
There was a problem hiding this comment.
1. Missing pad_delete regression test 📘 Rule violation ⚙ Maintainability
This PR changes pad deletion behavior on both the client and server but does not include an automated regression test that would fail if the fix were reverted. Without test coverage, the delete race condition (and related redirect behavior) can be reintroduced unnoticed.
Agent Prompt
## Issue description
The Delete Pad bug fix is not accompanied by a regression test, so the race-condition/redirect behavior can regress without being caught by CI.
## Issue Context
This PR changes the client to wait for `{disconnect: 'deleted'}` before navigating and changes the server to `await` pad removal. Add a deterministic automated test that fails if these changes are reverted.
## Fix Focus Areas
- src/tests/backend/specs/messages.ts[57-258]
- src/tests/backend/common.ts[254-264]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Summary
pad_editor.ts): The delete pad handler now waits for the server's response before navigating:{disconnect: 'deleted'}on themessageevent — navigates to/on successshoutevent — shows an alert when a non-creator tries to delete (server sends an error message instead of deleting)/if the server doesn't respond (socket dropped, etc.)PadMessageHandler.ts):awaitthepad.remove()call so the deletion completes beforekickSessionsFromPadsends the disconnect response.Root Cause
The delete pad click handler called
sendMessagethen immediately setwindow.location.href = '/'. In Firefox (and mobile Chrome), the browser tears down the WebSocket connection during page navigation before the outgoing message is flushed. The message never reaches the server, so the pad is never deleted — but the user sees the home page and thinks it worked.Additionally, when a non-creator tries to delete, the server sends a
shoutMessageon theshoutevent (not a disconnect). The old code navigated away before this could be received, so the user never saw the error. Now the client listens for this and displays the message.Test plan
messages.tstests pass (10/10)Fixes #7306
Fixes #7311
🤖 Generated with Claude Code