我创建了一个例子来展示might会发生什么:
typedef State = ({String userName, bool isLoading, String error});
State state = (userName: 'not set', isLoading: true, error: 'nothing');
void signInWithEmail({
required String email,
required String password,
Function? errorCallback,
}) async {
if (errorCallback == null) {
final userName = await Future.delayed(Duration.zero, () => 'Nick2001');
state = (userName: userName, isLoading: false, error: 'nothing');
} else {
throw errorCallback();
}
}
void main() async {
try {
signInWithEmail(
email: 'a@b.com',
password: '1234',
errorCallback: () => 'User not registered.',
);
print(state);
} catch (e) {
print('Caught error in main:');
print(' $e');
}
}
尽管catch块已设置为捕获每个可能的异常,但该程序仍会生成以下控制台输出.
$ dart main.dart
State: (error: nothing, isLoading: true, userName: not set)
Unhandled exception:
Exception: User not registered.
#0 signInWithEmail (file:///work/main.dart:14:5)
#1 main (file:///work/main.dart:20:5)
#2 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
现在我们将函数signInWithEmail
的签名更改为返回Future<void>
并在main中等待该函数:
Future<void> signInWithEmail({
required String email,
required String password,
Function? errorCallback,
}) async {
if (errorCallback == null) {
final userName = await Future.delayed(Duration.zero, () => 'Nick2001');
state = (userName: userName, isLoading: false, error: 'nothing');
} else {
throw errorCallback();
}
}
void main() async {
try {
await signInWithEmail(
email: 'a@b.com',
password: '1234',
errorCallback: () => Exception('User not registered.'),
);
print('State: $state');
} catch (e) {
print('Caught error in main:');
print(' $e');
}
}
运行此程序会产生预期的输出:
Caught error in main:
Exception: User not registered.
有关详细解释,请参阅Handling errors in void Dart function marked async.
简而言之:标记为"spec"的函数中引发的错误是future 错误.如果该函数在try-catch块中等待为not,那么在同步执行的try-catch块完成后将抛出future 错误,因此不会被捕获.