diff --git a/CHANGELOG.md b/CHANGELOG.md index f96ce7d..204d1fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.15.0 * `getSystemDevices(withServices:)` now sets several generic services by default as filter * `getConnectionState` on Android will now return `BleConnectionState.disconnected` if device is connected to the system but not to the app +* Improve callback error handling ## 0.14.0 * BREAKING CHANGE: `bleDevice.name` now filters out non-printable characters diff --git a/lib/src/ble_command_queue.dart b/lib/src/ble_command_queue.dart index 245d4d4..2d5449b 100644 --- a/lib/src/ble_command_queue.dart +++ b/lib/src/ble_command_queue.dart @@ -32,7 +32,9 @@ class BleCommandQueue { Queue _newQueue(String id) { final queue = Queue(); queue.onRemainingItemsUpdate = (int items) { - onQueueUpdate?.call(id, items); + try { + onQueueUpdate?.call(id, items); + } catch (_) {} }; _queueMap[id] = queue; return queue; diff --git a/lib/src/models/ble_connection_update.dart b/lib/src/models/ble_connection_update.dart index 26bb98f..f9727a7 100644 --- a/lib/src/models/ble_connection_update.dart +++ b/lib/src/models/ble_connection_update.dart @@ -1,8 +1,10 @@ class BleConnectionUpdate { + final String deviceId; final bool isConnected; final String? error; BleConnectionUpdate({ + required this.deviceId, required this.isConnected, this.error, }); diff --git a/lib/src/universal_ble.dart b/lib/src/universal_ble.dart index 3dc98a0..9e30020 100644 --- a/lib/src/universal_ble.dart +++ b/lib/src/universal_ble.dart @@ -101,13 +101,19 @@ class UniversalBle { } } }, + onError: (error) { + if (!completer.isCompleted) { + connectionSubscription?.cancel(); + completer.completeError(ConnectionException(error)); + } + }, ); _platform .connect(deviceId, connectionTimeout: connectionTimeout) .catchError( (error) { - if (completer.isCompleted == false) { + if (!completer.isCompleted) { connectionSubscription?.cancel(); completer.completeError(ConnectionException(error)); } diff --git a/lib/src/universal_ble_platform_interface.dart b/lib/src/universal_ble_platform_interface.dart index 30ace50..818352d 100644 --- a/lib/src/universal_ble_platform_interface.dart +++ b/lib/src/universal_ble_platform_interface.dart @@ -3,10 +3,14 @@ import 'dart:typed_data'; import 'package:universal_ble/universal_ble.dart'; abstract class UniversalBlePlatform { - StreamController<({String deviceId, bool isConnected, String? error})>? - _connectionStreamController; - + // Do not use these directly to push updates + OnScanResult? onScanResult; + OnConnectionChange? onConnectionChange; + OnValueChange? onValueChange; + OnAvailabilityChange? onAvailabilityChange; + OnPairingStateChange? onPairingStateChange; final Map _pairStateMap = {}; + StreamController? _connectionStreamController; Future getBluetoothAvailabilityState(); @@ -62,49 +66,49 @@ abstract class UniversalBlePlatform { Stream connectionStream(String deviceId) { _setupConnectionStreamIfRequired(); - return _connectionStreamController!.stream - .where((event) => event.deviceId == deviceId) - .map((event) => BleConnectionUpdate( - isConnected: event.isConnected, - error: event.error, - )); + return _connectionStreamController!.stream; } void updateScanResult(BleDevice bleDevice) { - onScanResult?.call(bleDevice); + try { + onScanResult?.call(bleDevice); + } catch (_) {} } void updateConnection(String deviceId, bool isConnected, [String? error]) { - onConnectionChange?.call(deviceId, isConnected, error); - _connectionStreamController?.add(( + _connectionStreamController?.add(BleConnectionUpdate( deviceId: deviceId, isConnected: isConnected, error: error, )); + + try { + onConnectionChange?.call(deviceId, isConnected, error); + } catch (_) {} } void updateCharacteristicValue( String deviceId, String characteristicId, Uint8List value) { - onValueChange?.call( - deviceId, BleUuidParser.string(characteristicId), value); + try { + onValueChange?.call( + deviceId, BleUuidParser.string(characteristicId), value); + } catch (_) {} } void updateAvailability(AvailabilityState state) { - onAvailabilityChange?.call(state); + try { + onAvailabilityChange?.call(state); + } catch (_) {} } void updatePairingState(String deviceId, bool isPaired) { if (_pairStateMap[deviceId] == isPaired) return; _pairStateMap[deviceId] = isPaired; - onPairingStateChange?.call(deviceId, isPaired); - } - // Do not use these directly to push updates - OnScanResult? onScanResult; - OnConnectionChange? onConnectionChange; - OnValueChange? onValueChange; - OnAvailabilityChange? onAvailabilityChange; - OnPairingStateChange? onPairingStateChange; + try { + onPairingStateChange?.call(deviceId, isPaired); + } catch (_) {} + } /// Creates an auto disposable streamController void _setupConnectionStreamIfRequired() {