mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-06-01 22:19:18 +02:00
fix: rethrow CancellationException in suspend catch blocks
Three suspend functions in BleRadioTransport caught Exception without rethrowing CancellationException, which could silently swallow coroutine cancellation: - findDevice(): scan retry loop would continue even after cancellation - attemptConnection(): bond() failure handler swallowed cancellation - onConnected(): RSSI read failure handler swallowed cancellation Also replace runCatching with safeCatching in two suspend contexts: - RadioConfigViewModel.probeMqttConnection() - LegacyDfuTransport DFU version read Per project rules: use safeCatching in coroutine/suspend contexts, keep runCatching only in cleanup/teardown or non-suspend code.
This commit is contained in:
+6
@@ -182,6 +182,8 @@ class BleRadioTransport(
|
||||
}
|
||||
}
|
||||
if (d != null) return d
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
Logger.v(e) { "[$address] Scan attempt failed or timed out" }
|
||||
}
|
||||
@@ -243,6 +245,8 @@ class BleRadioTransport(
|
||||
try {
|
||||
bluetoothRepository.bond(device)
|
||||
Logger.i { "[$address] Bonding successful" }
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
Logger.w(e) { "[$address] Bonding failed, attempting connection anyway" }
|
||||
}
|
||||
@@ -301,6 +305,8 @@ class BleRadioTransport(
|
||||
val rssi = retryBleOperation(tag = address) { device.readRssi() }
|
||||
Logger.d { "[$address] Connection confirmed. Initial RSSI: $rssi dBm" }
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
Logger.w(e) { "[$address] Failed to read initial connection RSSI" }
|
||||
}
|
||||
|
||||
+1
-1
@@ -142,7 +142,7 @@ class LegacyDfuTransport(
|
||||
// Best-effort DFU Version read — gate out unsupported old bootloaders (SDK ≤ 6).
|
||||
val versionChar = service.characteristic(LEGACY_DFU_VERSION_UUID)
|
||||
val version =
|
||||
runCatching { service.read(versionChar) }
|
||||
safeCatching { service.read(versionChar) }
|
||||
.map { bytes ->
|
||||
if (bytes.size >= 2) (bytes[0].toInt() and 0xFF) or ((bytes[1].toInt() and 0xFF) shl 8) else -1
|
||||
}
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import org.jetbrains.compose.resources.StringResource
|
||||
import org.koin.core.annotation.InjectedParam
|
||||
import org.koin.core.annotation.KoinViewModel
|
||||
import org.meshtastic.core.common.util.CommonUri
|
||||
import org.meshtastic.core.common.util.safeCatching
|
||||
import org.meshtastic.core.domain.usecase.settings.AdminActionsUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportProfileUseCase
|
||||
import org.meshtastic.core.domain.usecase.settings.ExportSecurityConfigUseCase
|
||||
@@ -165,7 +166,7 @@ open class RadioConfigViewModel(
|
||||
probeJob =
|
||||
viewModelScope.launch {
|
||||
val result =
|
||||
runCatching { mqttManager.probe(address, tlsEnabled, username, password) }
|
||||
safeCatching { mqttManager.probe(address, tlsEnabled, username, password) }
|
||||
.getOrElse { e ->
|
||||
Logger.w(e) { "MQTT probe threw" }
|
||||
MqttProbeStatus.Other(message = e.message)
|
||||
|
||||
Reference in New Issue
Block a user