Skip to content

fix(ble): Handle scan registration failure#6019

Merged
jamesarich merged 2 commits into
meshtastic:mainfrom
jeremiah-k:bugfix/ble-scan-registration-failure
Jun 30, 2026
Merged

fix(ble): Handle scan registration failure#6019
jamesarich merged 2 commits into
meshtastic:mainfrom
jeremiah-k:bugfix/ble-scan-registration-failure

Conversation

@jeremiah-k

@jeremiah-k jeremiah-k commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Overview

This pull request handles an Android BLE scan startup failure observed in field logs.

In that failure path, Android rejected BLE scanner registration with SCAN_FAILED_APPLICATION_REGISTRATION_FAILED. That means the discovery scan never actually started: there were no advertisements to wait for and no device-discovery result to recover from. The adapter was enabled and there was no permission exception, but Android reported that the app could not be registered for scanning.

Before this change, that failure escaped from the scan coroutine as a generic [startBleScan] unhandled exception. The scan state reset, and the app could immediately try again, creating repeated scanner-registration failures without a useful recovery message.

This change makes that scan-start failure explicit: the app classifies it near the scanner adapter, clears scan state, disables immediate BLE auto-scan retry, shows a recovery warning, and allows manual retry after a short cooldown.

Key Changes

  • Added a typed BLE scan startup failure for Android scanner registration failure.
  • Wrapped Kable scanner-registration failures as BleScanStartException.
  • Kept the Android/Kable message matching narrow and local to the scanner adapter.
  • Preserved cancellation and unrelated scanner exceptions.
  • Stopped treating scan startup failure as a generic [startBleScan] unhandled exception.
  • Ensured failed scan startup clears scanning state and scan job state.
  • Disabled BLE auto-scan after scan-start failure to avoid immediate retry loops.
  • Added a short retry cooldown before allowing another BLE discovery scan.
  • Surfaced a user-facing recovery message.
  • Preserved BLE/Network scan mutual exclusion.

Testing

  • Added coverage for direct Android scanner registration failure wrapping.
  • Added coverage for wrapped cause-chain scanner registration failure wrapping.
  • Added coverage proving unrelated IllegalStateException failures are preserved.
  • Added coverage proving scan startup failure clears scanning state.
  • Added coverage proving scan startup failure disables BLE auto-scan and surfaces an error.
  • Added coverage proving immediate retry is blocked during cooldown and manual retry is allowed after cooldown.
  • Added coverage proving stopBleScan() remains idempotent after failed startup.
  • Verified in a normal field run that BLE discovery, selection, connection setup, radio session readiness, and mesh handshake still complete successfully.

Migration Notes

  • No user data migration is required.
  • Existing BLE addresses and OS bonds are unchanged.
  • This only changes handling of Android BLE discovery scan startup failures.

Summary by CodeRabbit

  • New Features

    • Added a user-facing message for Bluetooth scan start failures.
    • Improved Bluetooth scanning to handle startup failures more gracefully, with automatic retry cooldowns.
  • Bug Fixes

    • Scan start errors are now detected and surfaced instead of failing silently.
    • Bluetooth auto-scan is disabled temporarily after repeated startup failures to prevent rapid retries.
    • Scanning state is now cleared correctly after a failed scan start.

Android reports BLE scan-start registration failure
(SCAN_FAILED_APPLICATION_REGISTRATION_FAILED) via Kable as an
IllegalStateException whose message contains 'app cannot be
registered'. Add a typed BleScanStartException wrapper with a
bounded cause-chain walker that detects this pattern. Unrelated
IllegalStateExceptions pass through unchanged.
Catch BleScanStartException in startBleScan: clear scanning state,
disable auto-scan, start a 15-second retry cooldown with generation-
guarded try/finally, and surface a user-facing warning. Uses
safeCatchingAll for the error string lookup because compose-resources
can throw ExceptionInInitializerError before the resource system is
ready (e.g. in unit tests).
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 09d43b09-597f-42a8-9ceb-93a3dd9242dc

📥 Commits

Reviewing files that changed from the base of the PR and between ce1a9fc and e816962.

📒 Files selected for processing (7)
  • .skills/compose-ui/strings-index.txt
  • core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/BleScanStartException.kt
  • core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt
  • core/ble/src/commonTest/kotlin/org/meshtastic/core/ble/KableBleConnectionTest.kt
  • core/resources/src/commonMain/composeResources/values/strings.xml
  • feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ScannerViewModel.kt
  • feature/connections/src/commonTest/kotlin/org/meshtastic/feature/connections/ScannerViewModelTest.kt

📝 Walkthrough

Walkthrough

Introduces BleScanStartException and BleScanStartFailureReason to model BLE scan start failures. KableBleScanner.scan() now wraps IllegalStateException from Android scan registration errors into this typed exception. ScannerViewModel catches it, disables auto-scan, surfaces a localized error, and enforces a retry cooldown. Tests and string resources are added.

Changes

BLE Scan Start Failure Handling

Layer / File(s) Summary
BleScanStartException model and string resources
core/ble/.../BleScanStartException.kt, core/resources/.../strings.xml, .skills/compose-ui/strings-index.txt
Defines BleScanStartFailureReason enum with ApplicationRegistrationFailed and BleScanStartException subclassing IllegalStateException. Adds localized bluetooth_scan_start_failed string resource and registers the key in the strings index.
KableBleScanner exception wrapping
core/ble/.../KableBleScanner.kt, core/ble/.../KableBleConnectionTest.kt
Adds try/catch in scan() to rethrow CancellationException and convert matched IllegalStateExceptions to BleScanStartException via cause-chain walking (asBleScanStartExceptionOrNull) and message matching (isApplicationRegistrationFailure). Tests cover direct, nested, and unrelated failure cases.
ScannerViewModel failure handler and retry cooldown
feature/connections/.../ScannerViewModel.kt
Catches BleScanStartException in the scan coroutine, routes it to handleBleScanStartFailure() which clears scan state, disables persisted BLE auto-scan, sets a localized warning error message, and starts a timed cooldown via startBleScanRetryCooldown(). startBleScan() precondition guards against starting during cooldown.
ScannerViewModel tests
feature/connections/.../ScannerViewModelTest.kt
Adds failingScanFlow() helper and three new tests: failure clears state and surfaces error, cooldown blocks immediate retry but allows retry after timeout, and stopBleScan is idempotent after failed startup.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: handling BLE scan registration/start failures.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@jeremiah-k jeremiah-k marked this pull request as ready for review June 29, 2026 22:10
@github-actions github-actions Bot added the bugfix PR tag label Jun 29, 2026
@jamesarich jamesarich added the bug Something isn't working label Jun 29, 2026
@jamesarich jamesarich added this pull request to the merge queue Jun 29, 2026
Merged via the queue into meshtastic:main with commit 4f8aced Jun 30, 2026
18 of 19 checks passed
@jeremiah-k jeremiah-k deleted the bugfix/ble-scan-registration-failure branch June 30, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working bugfix PR tag

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants