fix(sync): surface attachment/folder restore failures (audit 2.3)
applyRemoteSnapshot swallowed attachment + folder restore errors in silent catch blocks. Count them (attFailed/folderFailed) and warn in a toast after the sync summary. These don't abort the push (the entry synced, only its attachment/folder didn't) unlike a failed entry import. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-5
@@ -273,8 +273,8 @@ async function buildSyncSnapshot() {
|
||||
}
|
||||
|
||||
async function applyRemoteSnapshot(remote) {
|
||||
if (!remote || !Array.isArray(remote.entries)) return { added:0, updated:0, deleted:0, failed:0 };
|
||||
let added = 0, updated = 0, deleted = 0, failed = 0;
|
||||
if (!remote || !Array.isArray(remote.entries)) return { added:0, updated:0, deleted:0, failed:0, attFailed:0, folderFailed:0 };
|
||||
let added = 0, updated = 0, deleted = 0, failed = 0, attFailed = 0, folderFailed = 0;
|
||||
|
||||
// Ensure state.entries reflects the live DB before we read updated_at
|
||||
// for the resurrection arbitration below — a restore-then-sync must
|
||||
@@ -356,7 +356,7 @@ async function applyRemoteSnapshot(remote) {
|
||||
name: f.name, color: f.color || '', icon: f.icon || '',
|
||||
}),
|
||||
});
|
||||
} catch (_) {}
|
||||
} catch (_) { folderFailed++; }
|
||||
}
|
||||
await loadFolders();
|
||||
}
|
||||
@@ -410,7 +410,7 @@ async function applyRemoteSnapshot(remote) {
|
||||
size_bytes: a.size_bytes || bytes.length,
|
||||
}),
|
||||
});
|
||||
} catch (_) {}
|
||||
} catch (_) { attFailed++; }
|
||||
}
|
||||
}
|
||||
} catch (_) { failed++; }
|
||||
@@ -432,7 +432,7 @@ async function applyRemoteSnapshot(remote) {
|
||||
} catch (_) { failed++; }
|
||||
}
|
||||
}
|
||||
return { added, updated, deleted, failed };
|
||||
return { added, updated, deleted, failed, attFailed, folderFailed };
|
||||
}
|
||||
|
||||
// Update the inline sync-status label next to the button. Empty string
|
||||
@@ -623,5 +623,15 @@ async function runSyncNow(_attempt) {
|
||||
'pushed ' + pushedCount + ' ' +
|
||||
(pushedCount === 1 ? 'entry' : 'entries');
|
||||
toast('Sync complete — ' + summary);
|
||||
|
||||
// Surface additive-restore gaps that used to be swallowed silently
|
||||
// (§2.3). These don't risk overwriting the remote — the entry synced,
|
||||
// only its attachment/folder didn't come down — so they warn, not abort.
|
||||
if (merged.attFailed || merged.folderFailed) {
|
||||
const parts = [];
|
||||
if (merged.attFailed) parts.push(merged.attFailed + ' attachment(s)');
|
||||
if (merged.folderFailed) parts.push(merged.folderFailed + ' folder(s)');
|
||||
toast(parts.join(' · ') + ' failed to sync — retry sync', 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user