这是我的问题的一个简单示例:
import 'dart:async';
void main() {
try {
Timer(Duration(seconds: 1), () {
throw TimeoutException('1 second has expired');
});
} catch (o) {
print("caught ${o.runtimeType}");
}
}
我想问题是计时器在 try-catch block 终止后完成倒计时,考虑到倒计时是异步的并初始化 Timer
那是成功的。如何在不改变Timer
的回调函数的情况下捕获异常?
在我的具体情况下,我使用 flutter_blue并在使用异步方法时遇到问题 BluetoothDevice#connect()
.
/// Establishes a connection to the Bluetooth Device.
Future<void> connect({
Duration? timeout,
bool autoConnect = true,
}) async {
var request = protos.ConnectRequest.create()
..remoteId = id.toString()
..androidAutoConnect = autoConnect;
Timer? timer;
if (timeout != null) {
timer = Timer(timeout, () {
disconnect();
throw TimeoutException('Failed to connect in time.', timeout);
});
}
await FlutterBlue.instance._channel
.invokeMethod('connect', request.writeToBuffer());
await state.firstWhere((s) => s == BluetoothDeviceState.connected);
timer?.cancel();
return;
}
我这样调用该方法:
try {
await (device as BluetoothDevice).connect(timeout: Duration(seconds: 1));
} catch (o) {
print("caught ${o.runtimeType}");
}
考虑到我等待BluetoothDevice#connect()
与 await
成功连接后(在方法结束时)定时器将被取消 timer?.cancel();
,我不知道为什么 try-catch 没有捕获以下 TimeoutException
:
E/flutter ( 3710): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: TimeoutException after 0:00:01.000000: Failed to connect in time.
E/flutter ( 3710): #0 BluetoothDevice.connect.<anonymous closure> (package:flutter_blue/src/bluetooth_device.dart:33:9)
E/flutter ( 3710): #1 _rootRun (dart:async/zone.dart:1346:47)
E/flutter ( 3710): #2 _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 3710): #3 _CustomZone.runGuarded (dart:async/zone.dart:1162:7)
E/flutter ( 3710): #4 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1202:23)
E/flutter ( 3710): #5 _rootRun (dart:async/zone.dart:1354:13)
E/flutter ( 3710): #6 _CustomZone.run (dart:async/zone.dart:1258:19)
E/flutter ( 3710): #7 _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:1186:23)
E/flutter ( 3710): #8 Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter ( 3710): #9 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19)
E/flutter ( 3710): #10 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5)
E/flutter ( 3710): #11 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
E/flutter ( 3710):
我看到堆栈跟踪从 BluetoothDevice#connect()
开始,但我不知道该怎么办。
我也尝试调用then((_) {}, (o) => print("caught ${o.runtimeType}"))
关于Future<void>
返回者 BluetoothDevice#connect()
然后在try-catch中等待它,但我没有成功。
有什么想法吗?
最佳答案
您正在使用的包中的 connect
方法写得不好。你没有做错任何事,无论是谁写的代码都做错了。如果您浏览该存储库的 GitHub Issues 部分,您会发现很多问题以及与此问题相关的拉取请求,例如 this以及它链接的问题/公关。
计时器回调中的代码存在于实例化计时器的函数之外。不可能直接捕获计时器回调中抛出的错误。
如果你想要超时,不要使用这个包提供的功能,使用原生Dart timeout
功能。
try {
await (device as BluetoothDevice).connect().timeout(Duration(seconds: 1));
} catch (o) {
print("caught ${o.runtimeType}");
}
关于flutter - Dart - 无法捕获异步异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68658256/