Repository navigation
fix(persistence): warn once and retry failed saves - #425
Merged
Merged
Conversation
Deploying podnotes with
|
| Latest commit: |
2e8c23f
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://616b6704.podnotes.pages.dev |
| Branch Preview URL: | https://fix-surface-write-failures.podnotes.pages.dev |
This was referenced Oct 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Show "PodNotes could not save your changes." once per failed-write streak, and retry pending changes on the existing 10-second checkpoint schedule. Recovery is silent, and retries stop after recovery or unload. Successful sessions add no idle writes.
Detection and retention already existed in f7400ba (#388). All 73 existing persistence tests pass on master
1587b27, including swallowed-write detection and pending-document retention. The live master reproduction already rejectssaveSettingsStrictwhen Obsidian swallows an adapter error. This PR adds the missing Notice and automatic idle retry. It keepssaveDataplus readback, including Obsidian's modification-time bookkeeping, merge behavior, and quit/unload ordering.Fixes #385.
Verification
Node v22.23.2, with commands run through
fnm exec --using 22 --:npm run lintnpm run format:checknpm run typechecknpm run buildnpm run testnpm run test:toolingnpm run docs:buildTMPDIR="$PWD/.tmp" npm run test:e2enpm run sizeExactly two new regression tests: Notice streaks and scheduled retry. Both fail against unchanged master and pass here. The retry test also covers repeated failures, zero idle writes after recovery, and stopping on unload. Removing the unload guard makes it fail.
Real Obsidian 1.14.4 on Linux, isolated vault
podnotes-fix-surface-write-failures. Feedhttp://podnotes.test:33289/feed.xml, PodNotes Fixture / Fixture Episode 1, 60-second WAV. The probe rejects writes only to.obsidian/plugins/podnotes/data.json, changes skip-forward length from 15 to 21 through Settings, then seeks and briefly plays/pauses beyond 30 seconds. Both the adapter and original file are restored infinally.npm run count:writes -- start,report, andstopconfirm parity for 24 seconds playing plus 11 seconds idle: 4 writes on both builds after an idle start, 3 on both after a recent pause, and zero extra idle writes. Payload traces show only progress changed; checkpoint gaps are 10,002-10,004 ms. The initial 3-versus-4 comparison used different times since the previous save; the matched runs reproduce both counts on both builds.Verification report, full SHA-256 snapshots, scripts and logs.
Live data.json SHA-256 evidence
d0c2d1638285b63f42806300b536f607fab1f0fb2426412f2c1993ef9f3ec319.d8d9be76953b05abae70a8bd6c7b9dab6785110fbf3a5d7226b5898857dc7f91.a967a5a7804c0eae6dd24dae4fa2087dd23d9cd284b9e108a0cebfba4a4241a0.cc04e0e0931da45618748a0d815ace987423cb5d68bee6ade11bf7e4260c6d15.Silent recovery screenshot.
The first full E2E attempt hit Chromium's Linux socket path limit during restart because its scratch directory was too long. The full rerun uses the shorter worktree-local
.tmp; no source change was needed. Independent GPT and Claude reviews found no critical issues; the Claude coverage finding was addressed in the existing retry test.Release impact
No schema, settings shape, API or URI changes; no migration. Existing unreadable-file refusals remain in effect. Read failures before a retry and the existing external-merge settlement edge are recorded as follow-ups in the evidence report.
Docs at release
Document the save-failure Notice, one warning per failure streak, retries of pending changes on the 10-second checkpoint schedule while the file remains readable, and silent recovery when saving succeeds. Published docs are unchanged.
Note
Retry failed data-file saves at checkpoints and warn once per streak
DataFileWriternow retries ordinary failed saves at checkpoint intervals and stops retrying once a save succeeds. The newonWriteFailedcallback fires once per failed-write streak, showing an Obsidian Notice.WriteRefusedErrorfor writes blocked by refusal state; these are rethrown without entering the retry or notify path.scheduleCheckpointso an unloaded writer does not create a checkpoint timer.Macroscope summarized 2e8c23f.