Skip to content

feat: add retry handling for transient sync failures#62

Merged
TheZupZup merged 1 commit into
mainfrom
claude/dreamy-brown-9HfXu
May 22, 2026
Merged

feat: add retry handling for transient sync failures#62
TheZupZup merged 1 commit into
mainfrom
claude/dreamy-brown-9HfXu

Conversation

@TheZupZup
Copy link
Copy Markdown
Owner

Improves NexaNote sync reliability on unstable networks.

Adds:

  • retry/backoff for transient WebDAV failures
  • explicit timeout handling
  • retryable sync report metadata
  • safer diagnostics in sync logs
  • tests for retry and non-retryable failures

This keeps the existing sync engine and file-based storage layout intact.

Details

  • Retry/backoff is centralized in a single WebDAVClient._execute choke point wrapping every network op (GET, PROPFIND, PUT, MKCOL). Defaults: 3 attempts with 0.5s/1s/2s backoff. Retries only transient conditions — timeouts, connection errors, and HTTP 429/502/503/504. Auth (401/403) and 404 are never retried.
  • Timeouts stay explicit on every call and are configurable via SyncConfig.timeout_seconds; the retry budget is configurable via SyncConfig.max_attempts / backoff_seconds.
  • Retryable state: when a sync fails for a transient reason, the report carries retryable: true, a sanitized transient_reason, and a suggested next_retry_after_seconds. Surfaced additively on POST /sync/trigger and written to the sync log. Sync state is never corrupted.
  • Diagnostics: the latest sync log now records per-operation attempt counts, the retryable flag, and the transient reason — relative DAV slug paths only, no credentials, no body content, no server URLs.

Test plan

  • transient 503 succeeds after retry (PUT and GET)
  • 401/404 are not retried (single attempt)
  • timeout/connection error retried then reported retryable
  • retry failure does not corrupt sync state (note stays LOCAL_ONLY)
  • sync log records retryable state without secrets/body/URLs
  • successful retry still produces a normal report
  • full suite: 301 passed

Note: developed on branch claude/dreamy-brown-9HfXu per the environment's branch requirement (task suggested feat/sync-network-reliability).


Generated by Claude Code

@TheZupZup TheZupZup marked this pull request as ready for review May 22, 2026 19:44
@TheZupZup TheZupZup merged commit 96cfeec into main May 22, 2026
1 check passed
@TheZupZup TheZupZup deleted the claude/dreamy-brown-9HfXu branch May 22, 2026 19:44
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3be518676b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread nexanote/sync/client.py
suggéré. Ne lève jamais, ne touche pas l'état de sync.
"""
client = self.client
attempts = list(getattr(client, "op_attempts", []) or [])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reset retry diagnostics before building each sync report

_collect_reliability_diagnostics() reads client.op_attempts wholesale, but that buffer is never cleared at the start of sync(). If the same NexaNoteSyncEngine instance runs multiple syncs, transient failures from an earlier run remain in op_attempts, so a later non-transient failure (for example, a 401 auth error) can be incorrectly reported as retryable=true with a stale transient reason. This can drive incorrect client retry behavior and misleading logs for long-lived engine instances.

Useful? React with 👍 / 👎.

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.

2 participants