Skip to content

fix(network): retry transient connection/IO failures to api.meshtastic.org#5870

Merged
jamesarich merged 1 commit into
mainfrom
claude/confident-sanderson-334c4a
Jun 19, 2026
Merged

fix(network): retry transient connection/IO failures to api.meshtastic.org#5870
jamesarich merged 1 commit into
mainfrom
claude/confident-sanderson-334c4a

Conversation

@jamesarich

Copy link
Copy Markdown
Collaborator

Why

Both Ktor HttpClient configs (Android engine on mobile, Java engine on desktop) installed HttpRequestRetry with only retryOnServerErrors(maxRetries = 3) + exponentialDelay(). Transient connection/IO failures to api.meshtastic.org — DNS blips, dropped sockets, read timeouts — were therefore not retried and surfaced immediately as failures. That is the common failure mode on flaky cellular, where a single retry would usually succeed.

Ktor's Java-engine IOException retry became reliable in 3.1/3.2 (KTOR-6770) and this repo is on Ktor 3.5.0, so enabling exception retry is now safe on both engines.

Changes

🐛 Bug Fixes

  • Add retryOnException(maxRetries = 3, retryOnTimeout = true) alongside the existing retryOnServerErrors rule so transient connection/IO/timeout failures are retried with the same backoff. maxRetries reuses the existing HttpClientDefaults.MAX_RETRIES, so it stays in lockstep with the server-error rule.

🛠️ Refactoring & Architecture

  • Centralize the retry policy as a single HttpRequestRetryConfig.configureDefaultRetry() extension in core/network's HttpClientDefaults — where the shared timeout/retry constants already live — and call it from both engines. Previously each engine duplicated the install(HttpRequestRetry) { … } block; now there is one definition, so the two clients can't drift.

Files

  • core/network/.../HttpClientDefaults.kt — new configureDefaultRetry() extension (commonMain; ktor-client-core is already a commonMain dep)
  • androidApp/.../di/NetworkModule.kt — call site now install(plugin = HttpRequestRetry) { configureDefaultRetry() }
  • desktopApp/.../di/DesktopKoinModule.kt — call site now install(HttpRequestRetry) { configureDefaultRetry() }

Testing Performed

Baseline verification run locally (worktree):

  • ./gradlew spotlessApply
  • ./gradlew detekt
  • ./gradlew assembleDebug
  • ./gradlew :core:network:allTests ✅ (56 tests)
  • ./gradlew :desktopApp:compileKotlin ✅ (verifies the Java-engine call site compiles)

No behavioral change beyond retry coverage; no new tests added (the change is wiring on the Ktor plugin config).

🤖 Generated with Claude Code

…c.org

Both the Android (Android engine) and Desktop (Java engine) Ktor clients
installed HttpRequestRetry with only retryOnServerErrors + exponentialDelay,
so transient connection/IO failures (DNS blips, dropped sockets, read
timeouts) surfaced immediately as errors instead of being retried — the
common failure mode on flaky cellular.

Add retryOnException(retryOnTimeout = true) alongside the existing 5xx rule,
sharing the same MAX_RETRIES (3). Ktor's Java-engine IOException retry is
reliable since 3.1/3.2 (KTOR-6770) and the repo is on 3.5.0.

Centralize the policy as a single configureDefaultRetry() extension in
core/network HttpClientDefaults (where the shared timeout/retry constants
already live) so both engines share one definition instead of duplicating
the install block.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added the bugfix PR tag label Jun 19, 2026
@jamesarich jamesarich added this pull request to the merge queue Jun 19, 2026
Merged via the queue into main with commit a5f9238 Jun 19, 2026
19 checks passed
@jamesarich jamesarich deleted the claude/confident-sanderson-334c4a branch June 19, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix PR tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant