Skip to content

fix(editor): hand committed edits to edit-sync even when the update throws - #488

Merged
mtskf merged 3 commits into
mainfrom
chore/sync-01-surface-unsent-edits
Nov 10, 2026
Merged

mtskf merged 3 commits into
mainfrom
chore/sync-01-surface-unsent-edits

Conversation

@mtskf

@mtskf mtskf commented Nov 10, 2026

Copy link
Copy Markdown
Owner

Summary

A committed edit could stay unsent with no sign of it: CodeMirror commits the state before its DOM phase and runs each update listener in its own try/catch, so a DOM throw skipped the edit-sync listener and a throw inside it was swallowed. The edit-sync notification now runs from dispatchTransactions' finally, and a failure to schedule surfaces as a send failure.

Changes

  • src/webview/editor.ts: move the docChanged → edit-sync hand-off (incl. the send-failure retry ordering) out of the updateListener into noteLocalChange(), called from dispatchTransactions in a finally and keyed on doc identity (a throw before the commit leaves the doc unchanged, so nothing is sent). A throw from noteLocalChange itself dispatches send-failure, so the banner shows and the next keystroke's local-edit-attempt retries with the whole document.
  • test/webview/editor-unsent-edit-faults.test.ts: fault injection for both arms: a widget whose toDOM throws (edit still posted after the debounce), and a wrapped createEditSync whose onLocalChange throws once (send-failure dispatched, next keystroke ships seedxy). Both tests fail without the editor.ts change.
  • CHANGELOG: Unreleased / Fixed entry.

No paste-specific ACK or resend: this is a property of every dispatch, so the fix sits on the common path.

Related

  • TODO: SYNC-01 (split out of the PASTE-03 plan review)

Test Plan

  • pnpm vitest run test/webview/editor-unsent-edit-faults.test.ts: red before the fix, green after
  • pnpm vitest run: 291 files / 6219 tests green
  • pnpm test:browser: 92 green
  • pnpm compile, Biome clean

…hrows

CodeMirror commits the new state before its DOM phase and wraps each
update listener in its own try/catch. A throw from the DOM phase skipped
the edit-sync listener entirely, and a throw inside it was logged and
swallowed, so a committed edit could stay unscheduled with no sign it
never reached the host.

Move the edit-sync notification into dispatchTransactions' finally,
keyed on doc identity (a throw before the commit leaves nothing to send),
and turn a throw from the scheduling step itself into a send failure so
the banner shows and the next keystroke retries.
@mtskf
mtskf merged commit 8ec9a17 into main Nov 10, 2026
2 checks passed
@mtskf
mtskf deleted the chore/sync-01-surface-unsent-edits branch November 10, 2026 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant