fix(client): network drops reconnecting behaviour#3775
fix(client): network drops reconnecting behaviour#3775icecrasher321 merged 8 commits intostagingfrom
Conversation
PR SummaryMedium Risk Overview Updates Adds extra server-side SSE logging around client disconnect/cancel in Written by Cursor Bugbot for commit 03d6cab. Configure here. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Greptile SummaryThis PR adds client-side disconnect resilience for SSE chat streams. When a live stream is interrupted by a network drop, the client now re-attaches by replaying buffered events from a batch endpoint and then opening a fresh SSE tail — looping until the server signals a terminal status. It also handles the race condition where a new message is sent while the server still has an active stream for the same chat (conflict error), rolling back the optimistic UI update and queuing the user's message as a Key changes:
One concrete bug found: Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant U as User
participant SC as sendMessage
participant ATES as attachToExistingStream
participant FSB as fetchStreamBatch
participant PSS as processSSEStream
participant SG as stopGeneration
participant F as finalize
U->>SC: send message
SC->>SC: POST /api/copilot/chat
alt Primary stream ends cleanly
SC->>PSS: processSSEStream(reader, assistantId)
PSS-->>SC: { sawStreamError, sawDoneEvent, lastEventId }
SC->>FSB: fetchStreamBatch(streamId, lastEventId, signal)
FSB-->>SC: { status, events }
alt Terminal status
SC->>F: finalize()
else Non-terminal (network drop)
SC->>ATES: attachToExistingStream(...)
loop Until terminal status or abort
ATES->>PSS: processSSEStream(replayStream)
PSS-->>ATES: termination result
ATES->>ATES: open live SSE tail
PSS-->>ATES: live termination result
ATES->>FSB: fetchStreamBatch(next batch)
FSB-->>ATES: { status, events }
end
ATES-->>SC: { aborted, error }
SC->>F: finalize()
end
else Conflict error (stream already active)
SC->>SC: rollback optimistic state
SC->>SC: setPendingRecoveryMessage(queuedMessage)
SC->>SC: preparePendingStreamRecovery(chatId)
SC->>ATES: attachToExistingStream(existing stream)
ATES-->>SC: { aborted, error }
SC->>F: finalize()
F->>F: detect pendingRecoveryMessage
F->>SC: sendMessage(recoveryMessage) [via queueMicrotask]
end
U-->>SG: stop generation (optional)
SG->>SG: abort controller, clear refs
Note over SG: ⚠️ pendingRecoveryMessage state NOT cleared
|
|
bugbot run |
|
bugbot run |
|
@greptile |
|
bugbot run |
|
bugbot run |
|
bugbot run |
|
bugbot run |
* fix(client): network drops reconnecting behaviour * address bugbot comments * address comments * address queued message conflicts during retries * fix more review comments * fix branch * fix non-clear bug * fix
Summary
Client side disconnect resilience
Type of Change
Testing
Tested manually
Checklist