Part of #2195.
Problem
syncBoards() (src/components/Board/Board.actions.js:790) always dispatches SYNC_BOARDS_SUCCESS when its outer try block completes, but every per-board operation in pushLocalChangesToApi (:759, :780) and every deletion verification in applyRemoteChangesToState (:603-613) swallows its own errors with console.error. As a result, the top-level syncError state is null even when half the batch failed, and the UI has no way to know that some boards are still out of sync.
Impact
- Users get no signal that a board failed to upload.
- Other gaps in this epic (communicator desync,
markToUpdate orphans) become invisible because the global status reads "success".
- Debugging in production relies entirely on
console.error lines.
Proposed direction
- Collect per-board failures inside
pushLocalChangesToApi and applyRemoteChangesToState into a structured result (e.g. { failed: [{ boardId, phase, error }] }).
- Dispatch
SYNC_BOARDS_SUCCESS with that payload, or a new SYNC_BOARDS_PARTIAL_SUCCESS action, so the reducer can populate syncError / a new syncWarnings field.
- Update the UI mapping table in
docs/sync-engine.md §12 to include the partial-failure state.
Acceptance criteria
- Failing one board push leaves
state.board.syncError (or equivalent) populated with which boards failed.
- All other boards still complete normally.
- No regression: a fully successful sync still produces a clean state.
Part of #2195.
Problem
syncBoards()(src/components/Board/Board.actions.js:790) always dispatchesSYNC_BOARDS_SUCCESSwhen its outertryblock completes, but every per-board operation inpushLocalChangesToApi(:759,:780) and every deletion verification inapplyRemoteChangesToState(:603-613) swallows its own errors withconsole.error. As a result, the top-levelsyncErrorstate isnulleven when half the batch failed, and the UI has no way to know that some boards are still out of sync.Impact
markToUpdateorphans) become invisible because the global status reads "success".console.errorlines.Proposed direction
pushLocalChangesToApiandapplyRemoteChangesToStateinto a structured result (e.g.{ failed: [{ boardId, phase, error }] }).SYNC_BOARDS_SUCCESSwith that payload, or a newSYNC_BOARDS_PARTIAL_SUCCESSaction, so the reducer can populatesyncError/ a newsyncWarningsfield.docs/sync-engine.md§12 to include the partial-failure state.Acceptance criteria
state.board.syncError(or equivalent) populated with which boards failed.